From d0d45b0bc87ed672c6bda11b12fe6423961c2225 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Wed, 20 Dec 2023 15:32:06 +0100 Subject: [PATCH 01/23] feat: add allowlist cache layer migration --- .../migrate/migrations/0216_functions_allowlist.sql | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 core/store/migrate/migrations/0216_functions_allowlist.sql diff --git a/core/store/migrate/migrations/0216_functions_allowlist.sql b/core/store/migrate/migrations/0216_functions_allowlist.sql new file mode 100644 index 00000000000..fc7541cd67f --- /dev/null +++ b/core/store/migrate/migrations/0216_functions_allowlist.sql @@ -0,0 +1,11 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE functions_allowlist( + allowed_address bytea CHECK (octet_length(allowed_address) = 20) PRIMARY KEY +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +DROP TABLE IF EXISTS functions_allowlist; +-- +goose StatementEnd From 39f308534a31c827c2f8af4653029fad27c4ddfa Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Thu, 21 Dec 2023 18:28:30 +0100 Subject: [PATCH 02/23] feat: add getAllowedSendersInRange and getAllowedSendersCount methods for Tos --- .../gas-snapshots/functions.gas-snapshot | 138 +++++++++--------- .../accessControl/TermsOfServiceAllowList.sol | 33 +++++ .../interfaces/ITermsOfServiceAllowList.sol | 13 ++ .../FunctionsTermsOfServiceAllowList.t.sol | 24 +++ .../functions_allow_list.go | 52 ++++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 191 insertions(+), 71 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index d0893969bff..18dbc02f79e 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,12 +1,12 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14579333) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14579311) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14579327) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14590747) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14590724) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14590696) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14590647) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14590636) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14590680) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14837866) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14837844) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14837860) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14849280) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14849257) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14849229) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14849180) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14849169) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14849213) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) @@ -28,7 +28,7 @@ FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 38251) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13302) FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 180763) -FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398312) +FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398356) FunctionsClient_Constructor:test_Constructor_Success() (gas: 7573) FunctionsClient_FulfillRequest:test_FulfillRequest_MaximumGas() (gas: 497786) FunctionsClient_FulfillRequest:test_FulfillRequest_MinimumGas() (gas: 198990) @@ -61,7 +61,7 @@ FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 280 FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 151496) FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321059) FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334680) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2509962) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2509984) FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540441) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17983) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12904) @@ -82,17 +82,17 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengt FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19048) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118479) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59347) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59369) FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 193436) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57925) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186932) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186976) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50947) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 286243) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65843) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65865) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57533) @@ -100,7 +100,7 @@ FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalid FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 292812) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193424) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193468) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30688) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293) @@ -109,30 +109,30 @@ FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437) FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 60676) FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13336) FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 38732) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60326) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 60987) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94677) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62693) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 215197) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137893) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164837) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60370) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61009) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94743) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62737) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 215241) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137959) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164903) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12946) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57809) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87177) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57831) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 114850) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18094) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95480) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95502) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15041) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57885) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89287) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57907) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 116960) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20148) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194325) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114506) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125832) -FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 74973) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194347) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114524) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125849) +FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 74995) FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7654) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28660) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28682) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17994) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 351726) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 351792) FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 16226) FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13101) FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 40903) @@ -168,23 +168,23 @@ FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() ( FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14981) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 176494) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27611) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57709) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27633) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57753) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15001) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75131) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75153) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17960) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20128) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68196) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 82749) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68218) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 82793) FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554) FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41111) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30260) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30282) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 15019) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57800) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87223) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57822) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 114896) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18049) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191858) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41979) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191880) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42001) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12891) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35594) @@ -192,34 +192,36 @@ FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (ga FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57754) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26390) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26412) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152576) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94830) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25837) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44348) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23597) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866530) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26003) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946562) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 103411) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152642) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 139549) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25888) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44424) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23648) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866581) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26054) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1991357) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 148225) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 51794) -FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12187) -FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19243) -FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15773) -FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11583) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15925) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23430) -FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15354) -FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 41957) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13525) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95199) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 51848) +FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12209) +FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19265) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16452) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20204) +FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15751) +FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11637) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15947) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23452) +FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15332) +FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 41935) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13480) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 139927) FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13727) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22073) -Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84690) -Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79087) -Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73375) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22051) +Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 129409) +Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79109) +Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73397) Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38546) Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 979631) Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 157578) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol index 3bb7c7b04cc..03a845bf496 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol @@ -19,7 +19,12 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.1.0"; + // Keep a count of the number of allowed sender Ids so that its possible to + // loop through all the current allowed senders via .getAllowedSendersInRange((). + uint64 private s_currentAllowedSenderId; + EnumerableSet.AddressSet private s_allowedSenders; + mapping(uint64 => address) private s_allowedSendersIdMap; mapping(address => bool) private s_blockedSenders; event AddedAccess(address user); @@ -29,6 +34,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, error InvalidSignature(); error InvalidUsage(); error RecipientIsBlocked(); + error InvalidCalldata(); TermsOfServiceAllowListConfig private s_config; @@ -92,6 +98,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // Add recipient to the allow list if (s_allowedSenders.add(recipient)) { + s_allowedSendersIdMap[++s_currentAllowedSenderId] = recipient; emit AddedAccess(recipient); } } @@ -101,6 +108,32 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, return s_allowedSenders.values(); } + /// @inheritdoc ITermsOfServiceAllowList + function getAllowedSendersCount() external view override returns (uint64) { + return s_currentAllowedSenderId; + } + + /// @inheritdoc ITermsOfServiceAllowList + function getAllowedSendersInRange( + uint64 allowedSenderIdStart, + uint64 allowedSenderIdEnd + ) external view override returns (address[] memory allowedSenders) { + if ( + allowedSenderIdStart > allowedSenderIdEnd || + allowedSenderIdEnd > s_currentAllowedSenderId || + s_currentAllowedSenderId == 0 + ) { + revert InvalidCalldata(); + } + + allowedSenders = new address[]((allowedSenderIdEnd - allowedSenderIdStart) + 1); + for (uint256 i = 0; i <= allowedSenderIdEnd - allowedSenderIdStart; ++i) { + allowedSenders[i] = s_allowedSendersIdMap[uint64(allowedSenderIdStart + i)]; + } + + return allowedSenders; + } + /// @inheritdoc IAccessController function hasAccess(address user, bytes calldata /* data */) external view override returns (bool) { if (!s_config.enabled) { diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol index 209d25c0ab3..de1982b3248 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol @@ -22,6 +22,19 @@ interface ITermsOfServiceAllowList { /// @return addresses - all allowed addresses function getAllAllowedSenders() external view returns (address[] memory); + /// @notice Get details about the total number of allowed senders + /// @return count - total number of allowed senders in the system + function getAllowedSendersCount() external view returns (uint64); + + /// @notice Retrieve a list of allowed senders using an inclusive range + /// @param allowedSenderIdStart - the ID of the allowed sender to start the range at + /// @param allowedSenderIdEnd - the ID of the allowed sender to end the range at + /// @return allowedSenders - all allowed addresses + function getAllowedSendersInRange( + uint64 allowedSenderIdStart, + uint64 allowedSenderIdEnd + ) external view returns (address[] memory allowedSenders); + /// @notice Allows access to the sender based on acceptance of the Terms of Service /// @param acceptor - The wallet address that has accepted the Terms of Service on the UI /// @param recipient - The recipient address that the acceptor is taking responsibility for diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol index 08c981dd4f9..81e2621e40c 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol @@ -247,6 +247,30 @@ contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders is FunctionsOwner } } +/// @notice #getAllowedSendersInRange +contract FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange is FunctionsOwnerAcceptTermsOfServiceSetup { + function test_GetAllowedSendersInRange_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + address[] memory expectedSenders = new address[](1); + expectedSenders[0] = OWNER_ADDRESS; + + assertEq(s_termsOfServiceAllowList.getAllowedSendersInRange(1, 1), expectedSenders); + } + + function test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint64 lastAllowedSenderId = s_termsOfServiceAllowList.getAllowedSendersCount(); + vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); + s_termsOfServiceAllowList.getAllowedSendersInRange(1, lastAllowedSenderId + 1); + } +} + /// @notice #hasAccess contract FunctionsTermsOfServiceAllowList_HasAccess is FunctionsRoutesSetup { function test_HasAccess_FalseWhenEnabled() public { diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go index b0c4894f14c..64f8d2f489a 100644 --- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go +++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go @@ -36,8 +36,8 @@ type TermsOfServiceAllowListConfig struct { } var TermsOfServiceAllowListMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b50604051620012c9380380620012c9833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160058054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b610fcf80620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100df5760003560e01c806382184c7b1161008c578063a39b06e311610066578063a39b06e3146101b8578063a5e1d61d146101d9578063c3f909d4146101ec578063f2fde38b1461024b57600080fd5b806382184c7b1461016a57806389f9a2c41461017d5780638da5cb5b1461019057600080fd5b80636b14daf8116100bd5780636b14daf81461012a57806379ba50971461014d578063817ef62e1461015557600080fd5b8063181f5a77146100e45780633908c4d41461010257806347663acb14610117575b600080fd5b6100ec61025e565b6040516100f99190610c54565b60405180910390f35b610115610110366004610ce9565b61027a565b005b610115610125366004610d4a565b6104f5565b61013d610138366004610d65565b610580565b60405190151581526020016100f9565b6101156105aa565b61015d6106ac565b6040516100f99190610de8565b610115610178366004610d4a565b6106bd565b61011561018b366004610e42565b610750565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f9565b6101cb6101c6366004610ecb565b61080b565b6040519081526020016100f9565b61013d6101e7366004610d4a565b610869565b60408051808201825260008082526020918201528151808301835260055460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff6101009092048216928401928352845190815291511691810191909152016100f9565b610115610259366004610d4a565b6108aa565b6040518060600160405280602c8152602001610f97602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602052604090205460ff16156102da576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006102e6868661080b565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206005546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156103c0573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610417576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061045c57503373ffffffffffffffffffffffffffffffffffffffff87161480159061045c5750333b155b15610493576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61049e6002866108be565b156104ed5760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b6104fd6108e0565b73ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60055460009060ff16610595575060016105a3565b6105a0600285610963565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610630576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606106b86002610992565b905090565b6106c56108e0565b6106d060028261099f565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19101610575565b6107586108e0565b805160058054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a9101610575565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b1660348201526000906048016040516020818303038152906040528051906020012090505b92915050565b60055460009060ff1661087e57506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b6108b26108e0565b6108bb816109c1565b50565b60006105a38373ffffffffffffffffffffffffffffffffffffffff8416610ab6565b60005473ffffffffffffffffffffffffffffffffffffffff163314610961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610627565b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156105a3565b606060006105a383610b05565b60006105a38373ffffffffffffffffffffffffffffffffffffffff8416610b61565b3373ffffffffffffffffffffffffffffffffffffffff821603610a40576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610627565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610afd57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610863565b506000610863565b606081600001805480602002602001604051908101604052809291908181526020018280548015610b5557602002820191906000526020600020905b815481526020019060010190808311610b41575b50505050509050919050565b60008181526001830160205260408120548015610c4a576000610b85600183610efe565b8554909150600090610b9990600190610efe565b9050818114610bfe576000866000018281548110610bb957610bb9610f38565b9060005260206000200154905080876000018481548110610bdc57610bdc610f38565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610c0f57610c0f610f67565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610863565b6000915050610863565b600060208083528351808285015260005b81811015610c8157858101830151858201604001528201610c65565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ce457600080fd5b919050565b600080600080600060a08688031215610d0157600080fd5b610d0a86610cc0565b9450610d1860208701610cc0565b93506040860135925060608601359150608086013560ff81168114610d3c57600080fd5b809150509295509295909350565b600060208284031215610d5c57600080fd5b6105a382610cc0565b600080600060408486031215610d7a57600080fd5b610d8384610cc0565b9250602084013567ffffffffffffffff80821115610da057600080fd5b818601915086601f830112610db457600080fd5b813581811115610dc357600080fd5b876020828501011115610dd557600080fd5b6020830194508093505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015610e3657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610e04565b50909695505050505050565b600060408284031215610e5457600080fd5b6040516040810181811067ffffffffffffffff82111715610e9e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405282358015158114610eb157600080fd5b8152610ebf60208401610cc0565b60208201529392505050565b60008060408385031215610ede57600080fd5b610ee783610cc0565b9150610ef560208401610cc0565b90509250929050565b81810381811115610863577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b50604051620016f4380380620016f4833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160068054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b6113fa80620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806382184c7b11610097578063a5e1d61d11610066578063a5e1d61d1461025a578063c3f909d41461026d578063cc7ebf49146102cc578063f2fde38b1461030a57600080fd5b806382184c7b1461019357806389f9a2c4146101a65780638da5cb5b146101b9578063a39b06e3146101e157600080fd5b806347663acb116100d357806347663acb1461014d5780636b14daf81461016057806379ba509714610183578063817ef62e1461018b57600080fd5b80630a8c9c24146100fa578063181f5a77146101235780633908c4d414610138575b600080fd5b61010d610108366004610f6f565b61031d565b60405161011a9190610fa2565b60405180910390f35b61012b6104e9565b60405161011a9190610ffc565b61014b61014636600461108c565b610505565b005b61014b61015b3660046110ed565b610851565b61017361016e366004611108565b6108dc565b604051901515815260200161011a565b61014b610906565b61010d610a08565b61014b6101a13660046110ed565b610a19565b61014b6101b43660046111ba565b610aac565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61024c6101ef366004611243565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161011a565b6101736102683660046110ed565b610b67565b60408051808201825260008082526020918201528151808301835260065460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161011a565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161011a565b61014b6103183660046110ed565b610ba8565b60608167ffffffffffffffff168367ffffffffffffffff161180610368575060015467ffffffffffffffff740100000000000000000000000000000000000000009091048116908316115b80610395575060015474010000000000000000000000000000000000000000900467ffffffffffffffff16155b156103cc576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d6838361129c565b6103e19060016112bd565b67ffffffffffffffff1667ffffffffffffffff8111156104035761040361118b565b60405190808252806020026020018201604052801561042c578160200160208202803683370190505b50905060005b61043c848461129c565b67ffffffffffffffff1681116104e157600460006104648367ffffffffffffffff88166112de565b67ffffffffffffffff168152602081019190915260400160002054825173ffffffffffffffffffffffffffffffffffffffff909116908390839081106104ac576104ac6112f1565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526104da81611320565b9050610432565b505b92915050565b6040518060600160405280602c81526020016113c2602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526005602052604090205460ff1615610565576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206006546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa158015610699573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16146106f0576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061073557503373ffffffffffffffffffffffffffffffffffffffff8716148015906107355750333b155b1561076c576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610777600286610bbc565b156108495784600460006001601481819054906101000a900467ffffffffffffffff166107a390611358565b825467ffffffffffffffff9182166101009390930a838102920219161790915581526020808201929092526040908101600020805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555191871682527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db4910160405180910390a15b505050505050565b610859610bde565b73ffffffffffffffffffffffffffffffffffffffff811660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60065460009060ff166108f1575060016108ff565b6108fc600285610c61565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461098c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6060610a146002610c90565b905090565b610a21610bde565b610a2c600282610c9d565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e191016108d1565b610ab4610bde565b805160068054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a91016108d1565b60065460009060ff16610b7c57506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460ff1690565b610bb0610bde565b610bb981610cbf565b50565b60006108ff8373ffffffffffffffffffffffffffffffffffffffff8416610db4565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610983565b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156108ff565b606060006108ff83610e03565b60006108ff8373ffffffffffffffffffffffffffffffffffffffff8416610e5f565b3373ffffffffffffffffffffffffffffffffffffffff821603610d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610983565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610dfb575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104e3565b5060006104e3565b606081600001805480602002602001604051908101604052809291908181526020018280548015610e5357602002820191906000526020600020905b815481526020019060010190808311610e3f575b50505050509050919050565b60008181526001830160205260408120548015610f48576000610e8360018361137f565b8554909150600090610e979060019061137f565b9050818114610efc576000866000018281548110610eb757610eb76112f1565b9060005260206000200154905080876000018481548110610eda57610eda6112f1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610f0d57610f0d611392565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104e3565b60009150506104e3565b803567ffffffffffffffff81168114610f6a57600080fd5b919050565b60008060408385031215610f8257600080fd5b610f8b83610f52565b9150610f9960208401610f52565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015610ff057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610fbe565b50909695505050505050565b600060208083528351808285015260005b818110156110295785810183015185820160400152820161100d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f6a57600080fd5b600080600080600060a086880312156110a457600080fd5b6110ad86611068565b94506110bb60208701611068565b93506040860135925060608601359150608086013560ff811681146110df57600080fd5b809150509295509295909350565b6000602082840312156110ff57600080fd5b6108ff82611068565b60008060006040848603121561111d57600080fd5b61112684611068565b9250602084013567ffffffffffffffff8082111561114357600080fd5b818601915086601f83011261115757600080fd5b81358181111561116657600080fd5b87602082850101111561117857600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000604082840312156111cc57600080fd5b6040516040810181811067ffffffffffffffff82111715611216577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461122957600080fd5b815261123760208401611068565b60208201529392505050565b6000806040838503121561125657600080fd5b61125f83611068565b9150610f9960208401611068565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104e1576104e161126d565b67ffffffffffffffff8181168382160190808211156104e1576104e161126d565b808201808211156104e3576104e361126d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113515761135161126d565b5060010190565b600067ffffffffffffffff8083168181036113755761137561126d565b6001019392505050565b818103818111156104e3576104e361126d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", } var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI @@ -198,6 +198,50 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllAllo return _TermsOfServiceAllowList.Contract.GetAllAllowedSenders(&_TermsOfServiceAllowList.CallOpts) } +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetAllowedSendersCount(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getAllowedSendersCount") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetAllowedSendersCount() (uint64, error) { + return _TermsOfServiceAllowList.Contract.GetAllowedSendersCount(&_TermsOfServiceAllowList.CallOpts) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllowedSendersCount() (uint64, error) { + return _TermsOfServiceAllowList.Contract.GetAllowedSendersCount(&_TermsOfServiceAllowList.CallOpts) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) { + var out []interface{} + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getAllowedSendersInRange", allowedSenderIdStart, allowedSenderIdEnd) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetAllowedSendersInRange(allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdStart, allowedSenderIdEnd) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllowedSendersInRange(allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdStart, allowedSenderIdEnd) +} + func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) { var out []interface{} err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getConfig") @@ -1193,6 +1237,10 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowList) Address() common.Addres type TermsOfServiceAllowListInterface interface { GetAllAllowedSenders(opts *bind.CallOpts) ([]common.Address, error) + GetAllowedSendersCount(opts *bind.CallOpts) (uint64, error) + + GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) + GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) GetMessage(opts *bind.CallOpts, acceptor common.Address, recipient common.Address) ([32]byte, error) diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 132f38507ad..508d517fe00 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,6 +1,6 @@ GETH_VERSION: 1.13.8 functions: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db -functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 6beec092fbb3b619dfe69f1ad23392b0bbaf00327b335e4080f921c7122a57e4 +functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 77e0180b0915b178f6acffacc6d04deb510b51ecc62b9d29770d271bc1eaf191 functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b From a72d063815dcfe612618366cb63157df7807b813 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Tue, 2 Jan 2024 17:47:24 +0100 Subject: [PATCH 03/23] feat: iterate over allowlist contract response, load and update allowlist --- .../gateway/handlers/functions/allowlist.go | 75 ++++++++++++++++++- .../handlers/functions/allowlist_test.go | 20 ++++- .../handlers/functions/handler.functions.go | 7 +- .../gateway/handlers/functions/mocks/orm.go | 63 ++++++++++++++++ .../gateway/handlers/functions/orm.go | 19 ++++- .../services/ocr2/plugins/functions/plugin.go | 10 +-- .../migrations/0216_functions_allowlist.sql | 5 +- 7 files changed, 181 insertions(+), 18 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 0a18d6e6d87..d30642ccd95 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -22,6 +22,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) +const defaultAllowlistCacheBatchSize = 100 + type OnchainAllowlistConfig struct { // ContractAddress is required ContractAddress common.Address `json:"contractAddress"` @@ -30,6 +32,7 @@ type OnchainAllowlistConfig struct { // UpdateFrequencySec can be zero to disable periodic updates UpdateFrequencySec uint `json:"updateFrequencySec"` UpdateTimeoutSec uint `json:"updateTimeoutSec"` + CacheBatchSize uint `json:"cacheBatchSize"` } // OnchainAllowlist maintains an allowlist of addresses fetched from the blockchain (EVM-only). @@ -50,6 +53,7 @@ type onchainAllowlist struct { config OnchainAllowlistConfig allowlist atomic.Pointer[map[common.Address]struct{}] + orm ORM client evmclient.Client contractV1 *functions_router.FunctionsRouter blockConfirmations *big.Int @@ -58,7 +62,7 @@ type onchainAllowlist struct { stopCh services.StopChan } -func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, lggr logger.Logger) (OnchainAllowlist, error) { +func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, orm ORM, lggr logger.Logger) (OnchainAllowlist, error) { if client == nil { return nil, errors.New("client is nil") } @@ -68,12 +72,20 @@ func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, if config.ContractVersion != 1 { return nil, fmt.Errorf("unsupported contract version %d", config.ContractVersion) } + + // if CacheBatchSize is not specified used the default value + if config.CacheBatchSize == 0 { + lggr.Info("CacheBatchSize not specified, using default size: ", defaultAllowlistCacheBatchSize) + config.CacheBatchSize = defaultAllowlistCacheBatchSize + } + contractV1, err := functions_router.NewFunctionsRouter(config.ContractAddress, client) if err != nil { return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err) } allowlist := &onchainAllowlist{ config: config, + orm: orm, client: client, contractV1: contractV1, blockConfirmations: big.NewInt(int64(config.BlockConfirmations)), @@ -101,6 +113,8 @@ func (a *onchainAllowlist) Start(ctx context.Context) error { cancel() } + a.loadCachedAllowedList() + a.closeWait.Add(1) go func() { defer a.closeWait.Done() @@ -172,17 +186,42 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b if err != nil { return errors.Wrap(err, "unexpected error during functions_allow_list.NewTermsOfServiceAllowList") } - addrList, err := tosContract.GetAllAllowedSenders(&bind.CallOpts{ + + idEnd, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, Context: ctx, }) if err != nil { - return errors.Wrap(err, "error calling GetAllAllowedSenders") + return errors.Wrap(err, "unexpected error during functions_allow_list.GetAllowedSendersCount") + } + + idStart := uint64(0) + allowedSenderList := make([]common.Address, 0) + for { + allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }, idStart, idEnd) + if err != nil { + return errors.Wrap(err, "error calling GetAllowedSendersInRange") + } + + allowedSenderList = append(allowedSenderList, allowedSendersBatch...) + + if len(allowedSendersBatch) < int(a.config.CacheBatchSize) { + break + } + + idStart += uint64(a.config.CacheBatchSize) } - a.update(addrList) + + a.update(allowedSenderList) + a.updateCache(allowedSenderList) return nil } + func (a *onchainAllowlist) update(addrList []common.Address) { newAllowlist := make(map[common.Address]struct{}) for _, addr := range addrList { @@ -191,3 +230,31 @@ func (a *onchainAllowlist) update(addrList []common.Address) { a.allowlist.Store(&newAllowlist) a.lggr.Infow("allowlist updated successfully", "len", len(addrList)) } + +func (a *onchainAllowlist) updateCache(addrList []common.Address) { + for id, addr := range addrList { + if err := a.orm.UpsertAllowedSender(int64(id), addr); err != nil { + a.lggr.Errorf("failed to update cache: %w", err) + } + } +} + +func (a *onchainAllowlist) loadCachedAllowedList() { + allowedList := make([]common.Address, 0) + offset := uint(0) + for { + asBatch, err := a.orm.GetAllowedSenders(offset, a.config.CacheBatchSize) + if err != nil { + break + } + + allowedList = append(allowedList, asBatch...) + + if len(asBatch) != int(a.config.CacheBatchSize) { + break + } + offset += a.config.CacheBatchSize + } + + a.update(allowedList) +} diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index fdaea81b2c0..6c436494c3e 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -17,6 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + fmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/mocks" ) const ( @@ -47,7 +48,12 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { ContractAddress: common.Address{}, BlockConfirmations: 1, } - allowlist, err := functions.NewOnchainAllowlist(client, config, logger.TestLogger(t)) + + orm := fmocks.NewORM(t) + orm.On("UpsertAllowedSender", int64(0), common.HexToAddress(addr1)).Return(nil) + orm.On("UpsertAllowedSender", int64(1), common.HexToAddress(addr2)).Return(nil) + + allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = allowlist.Start(testutils.Context(t)) @@ -72,7 +78,9 @@ func TestAllowlist_UnsupportedVersion(t *testing.T) { ContractAddress: common.Address{}, BlockConfirmations: 1, } - _, err := functions.NewOnchainAllowlist(client, config, logger.TestLogger(t)) + + orm := fmocks.NewORM(t) + _, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.Error(t, err) } @@ -92,7 +100,13 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { UpdateFrequencySec: 1, UpdateTimeoutSec: 1, } - allowlist, err := functions.NewOnchainAllowlist(client, config, logger.TestLogger(t)) + + orm := fmocks.NewORM(t) + orm.On("GetAllowedSenders", uint(0), uint(100)).Return([]common.Address{}, nil) + orm.On("UpsertAllowedSender", int64(0), common.HexToAddress(addr1)).Return(nil) + orm.On("UpsertAllowedSender", int64(1), common.HexToAddress(addr2)).Return(nil) + + allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = allowlist.Start(ctx) diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go index 2872c72f761..06ad2f50e47 100644 --- a/core/services/gateway/handlers/functions/handler.functions.go +++ b/core/services/gateway/handlers/functions/handler.functions.go @@ -111,7 +111,12 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con if err2 != nil { return nil, err2 } - allowlist, err2 = NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, lggr) + + orm, err2 := NewORM(db, lggr, qcfg, cfg.OnchainAllowlist.ContractAddress) + if err2 != nil { + return nil, err2 + } + allowlist, err2 = NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, orm, lggr) if err2 != nil { return nil, err2 } diff --git a/core/services/gateway/handlers/functions/mocks/orm.go b/core/services/gateway/handlers/functions/mocks/orm.go index 110675c8b55..d0b8dc6b4f9 100644 --- a/core/services/gateway/handlers/functions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/mocks/orm.go @@ -3,6 +3,7 @@ package mocks import ( + common "github.com/ethereum/go-ethereum/common" functions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" mock "github.com/stretchr/testify/mock" @@ -14,6 +15,43 @@ type ORM struct { mock.Mock } +// GetAllowedSenders provides a mock function with given fields: offset, limit, qopts +func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, offset, limit) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetAllowedSenders") + } + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]common.Address, error)); ok { + return rf(offset, limit, qopts...) + } + if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []common.Address); ok { + r0 = rf(offset, limit, qopts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(uint, uint, ...pg.QOpt) error); ok { + r1 = rf(offset, limit, qopts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetSubscriptions provides a mock function with given fields: offset, limit, qopts func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]functions.CachedSubscription, error) { _va := make([]interface{}, len(qopts)) @@ -51,6 +89,31 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]fu return r0, r1 } +// UpsertAllowedSender provides a mock function with given fields: id, allowedSender, qopts +func (_m *ORM) UpsertAllowedSender(id int64, allowedSender common.Address, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, id, allowedSender) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpsertAllowedSender") + } + + var r0 error + if rf, ok := ret.Get(0).(func(int64, common.Address, ...pg.QOpt) error); ok { + r0 = rf(id, allowedSender, qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // UpsertSubscription provides a mock function with given fields: subscription, qopts func (_m *ORM) UpsertSubscription(subscription functions.CachedSubscription, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) diff --git a/core/services/gateway/handlers/functions/orm.go b/core/services/gateway/handlers/functions/orm.go index b7ec8d865d1..8d351969463 100644 --- a/core/services/gateway/handlers/functions/orm.go +++ b/core/services/gateway/handlers/functions/orm.go @@ -20,6 +20,8 @@ import ( type ORM interface { GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSubscription, error) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error + GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) + UpsertAllowedSender(id int64, allowedSender common.Address, qopts ...pg.QOpt) error } type orm struct { @@ -29,11 +31,12 @@ type orm struct { var _ ORM = (*orm)(nil) var ( - ErrInvalidParameters = errors.New("invalid parameters provided to create a subscription cache ORM") + ErrInvalidParameters = errors.New("invalid parameters provided to create a functions contract cache ORM") ) const ( - tableName = "functions_subscriptions" + subscriptionsTableName = "functions_subscriptions" + allowlistTableName = "functions_allowlist" ) type cachedSubscriptionRow struct { @@ -68,7 +71,7 @@ func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSu ORDER BY subscription_id ASC OFFSET $2 LIMIT $3; - `, tableName) + `, subscriptionsTableName) err := o.q.WithOpts(qopts...).Select(&cacheSubscriptionRows, stmt, o.routerContractAddress, offset, limit) if err != nil { return cacheSubscriptions, err @@ -87,7 +90,7 @@ func (o *orm) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QO stmt := fmt.Sprintf(` INSERT INTO %s (subscription_id, owner, balance, blocked_balance, proposed_owner, consumers, flags, router_contract_address) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT (subscription_id, router_contract_address) DO UPDATE - SET owner=$2, balance=$3, blocked_balance=$4, proposed_owner=$5, consumers=$6, flags=$7, router_contract_address=$8;`, tableName) + SET owner=$2, balance=$3, blocked_balance=$4, proposed_owner=$5, consumers=$6, flags=$7, router_contract_address=$8;`, subscriptionsTableName) if subscription.Balance == nil { subscription.Balance = big.NewInt(0) @@ -130,3 +133,11 @@ func (cs *cachedSubscriptionRow) encode() CachedSubscription { }, } } + +func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { + return nil, nil +} + +func (o *orm) UpsertAllowedSender(id int64, allowedSender common.Address, qopts ...pg.QOpt) error { + return nil +} diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go index fd72b6fd38e..6c4f323c07a 100644 --- a/core/services/ocr2/plugins/functions/plugin.go +++ b/core/services/ocr2/plugins/functions/plugin.go @@ -134,7 +134,11 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs allServices = append(allServices, job.NewServiceAdapter(functionsReportingPluginOracle)) if pluginConfig.GatewayConnectorConfig != nil && s4Storage != nil && pluginConfig.OnchainAllowlist != nil && pluginConfig.RateLimiter != nil && pluginConfig.OnchainSubscriptions != nil { - allowlist, err2 := gwFunctions.NewOnchainAllowlist(conf.Chain.Client(), *pluginConfig.OnchainAllowlist, conf.Logger) + gwFunctionsORM, err := gwFunctions.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainSubscriptions.ContractAddress) + if err != nil { + return nil, errors.Wrap(err, "failed to create functions ORM") + } + allowlist, err2 := gwFunctions.NewOnchainAllowlist(conf.Chain.Client(), *pluginConfig.OnchainAllowlist, gwFunctionsORM, conf.Logger) if err2 != nil { return nil, errors.Wrap(err, "failed to create OnchainAllowlist") } @@ -142,10 +146,6 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs if err2 != nil { return nil, errors.Wrap(err, "failed to create a RateLimiter") } - gwFunctionsORM, err := gwFunctions.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainSubscriptions.ContractAddress) - if err != nil { - return nil, errors.Wrap(err, "failed to create functions ORM") - } subscriptions, err2 := gwFunctions.NewOnchainSubscriptions(conf.Chain.Client(), *pluginConfig.OnchainSubscriptions, gwFunctionsORM, conf.Logger) if err2 != nil { return nil, errors.Wrap(err, "failed to create a OnchainSubscriptions") diff --git a/core/store/migrate/migrations/0216_functions_allowlist.sql b/core/store/migrate/migrations/0216_functions_allowlist.sql index fc7541cd67f..5eb40e101b8 100644 --- a/core/store/migrate/migrations/0216_functions_allowlist.sql +++ b/core/store/migrate/migrations/0216_functions_allowlist.sql @@ -1,7 +1,10 @@ -- +goose Up -- +goose StatementBegin CREATE TABLE functions_allowlist( - allowed_address bytea CHECK (octet_length(allowed_address) = 20) PRIMARY KEY + id bigint, + router_contract_address bytea, + allowed_address bytea CHECK (octet_length(allowed_address) = 20) NOT NULL, + PRIMARY KEY(router_contract_address, id) ); -- +goose StatementEnd From 8e4840c89c8f7c932f14979bcd61fe474a80e93e Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Mon, 8 Jan 2024 12:15:29 +0100 Subject: [PATCH 04/23] feat: reduce gas by removing mapping and using EnumerableSet .length() and .at() methods --- .../gas-snapshots/functions.gas-snapshot | 38 +++++++++---------- .../accessControl/TermsOfServiceAllowList.sol | 18 ++++----- .../functions_allow_list.go | 2 +- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 18dbc02f79e..7cc9dc04223 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,12 +1,12 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14837866) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14837844) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14837860) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14849280) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14849257) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14849229) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14849180) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14849169) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14849213) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14751886) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14751864) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14751880) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14763300) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14763277) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14763249) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14763200) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14763189) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14763233) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) @@ -118,12 +118,12 @@ FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() ( FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164903) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12946) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57831) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 114850) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87228) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18094) FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95502) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15041) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57907) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 116960) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89338) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20148) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194347) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114524) @@ -181,7 +181,7 @@ FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41111) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30282) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 15019) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57822) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 114896) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87274) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18049) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191880) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42001) @@ -195,20 +195,20 @@ FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 5775 FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26412) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152642) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 139549) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94827) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25888) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44424) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23648) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866581) FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26054) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1991357) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 148225) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946635) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 103503) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469) FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 51848) FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12209) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19265) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16452) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20204) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16557) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20523) FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15751) FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11637) FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15947) @@ -216,10 +216,10 @@ FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (ga FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15332) FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 41935) FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13480) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 139927) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95205) FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13727) FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22051) -Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 129409) +Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84687) Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79109) Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73397) Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38546) diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol index 03a845bf496..ca58bf0216a 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol @@ -19,12 +19,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.1.0"; - // Keep a count of the number of allowed sender Ids so that its possible to - // loop through all the current allowed senders via .getAllowedSendersInRange((). - uint64 private s_currentAllowedSenderId; - EnumerableSet.AddressSet private s_allowedSenders; - mapping(uint64 => address) private s_allowedSendersIdMap; mapping(address => bool) private s_blockedSenders; event AddedAccess(address user); @@ -98,7 +93,6 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, // Add recipient to the allow list if (s_allowedSenders.add(recipient)) { - s_allowedSendersIdMap[++s_currentAllowedSenderId] = recipient; emit AddedAccess(recipient); } } @@ -110,25 +104,27 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, /// @inheritdoc ITermsOfServiceAllowList function getAllowedSendersCount() external view override returns (uint64) { - return s_currentAllowedSenderId; + return uint64(s_allowedSenders.length()); } - /// @inheritdoc ITermsOfServiceAllowList + /// @dev WARNING: getAllowedSendersInRange uses EnumerableSet .length() and .at() methods to iterate over the list + /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. + /// Evaluate if eventual consistency will satisfy your usecase before using it. function getAllowedSendersInRange( uint64 allowedSenderIdStart, uint64 allowedSenderIdEnd ) external view override returns (address[] memory allowedSenders) { if ( allowedSenderIdStart > allowedSenderIdEnd || - allowedSenderIdEnd > s_currentAllowedSenderId || - s_currentAllowedSenderId == 0 + allowedSenderIdEnd > s_allowedSenders.length() || + s_allowedSenders.length() == 0 ) { revert InvalidCalldata(); } allowedSenders = new address[]((allowedSenderIdEnd - allowedSenderIdStart) + 1); for (uint256 i = 0; i <= allowedSenderIdEnd - allowedSenderIdStart; ++i) { - allowedSenders[i] = s_allowedSendersIdMap[uint64(allowedSenderIdStart + i)]; + allowedSenders[i] = s_allowedSenders.at(uint256(allowedSenderIdStart + i - 1)); } return allowedSenders; diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go index 64f8d2f489a..314708ddabb 100644 --- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go +++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go @@ -37,7 +37,7 @@ type TermsOfServiceAllowListConfig struct { var TermsOfServiceAllowListMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b50604051620016f4380380620016f4833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160068054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b6113fa80620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806382184c7b11610097578063a5e1d61d11610066578063a5e1d61d1461025a578063c3f909d41461026d578063cc7ebf49146102cc578063f2fde38b1461030a57600080fd5b806382184c7b1461019357806389f9a2c4146101a65780638da5cb5b146101b9578063a39b06e3146101e157600080fd5b806347663acb116100d357806347663acb1461014d5780636b14daf81461016057806379ba509714610183578063817ef62e1461018b57600080fd5b80630a8c9c24146100fa578063181f5a77146101235780633908c4d414610138575b600080fd5b61010d610108366004610f6f565b61031d565b60405161011a9190610fa2565b60405180910390f35b61012b6104e9565b60405161011a9190610ffc565b61014b61014636600461108c565b610505565b005b61014b61015b3660046110ed565b610851565b61017361016e366004611108565b6108dc565b604051901515815260200161011a565b61014b610906565b61010d610a08565b61014b6101a13660046110ed565b610a19565b61014b6101b43660046111ba565b610aac565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61024c6101ef366004611243565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161011a565b6101736102683660046110ed565b610b67565b60408051808201825260008082526020918201528151808301835260065460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161011a565b60015474010000000000000000000000000000000000000000900467ffffffffffffffff1660405167ffffffffffffffff909116815260200161011a565b61014b6103183660046110ed565b610ba8565b60608167ffffffffffffffff168367ffffffffffffffff161180610368575060015467ffffffffffffffff740100000000000000000000000000000000000000009091048116908316115b80610395575060015474010000000000000000000000000000000000000000900467ffffffffffffffff16155b156103cc576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d6838361129c565b6103e19060016112bd565b67ffffffffffffffff1667ffffffffffffffff8111156104035761040361118b565b60405190808252806020026020018201604052801561042c578160200160208202803683370190505b50905060005b61043c848461129c565b67ffffffffffffffff1681116104e157600460006104648367ffffffffffffffff88166112de565b67ffffffffffffffff168152602081019190915260400160002054825173ffffffffffffffffffffffffffffffffffffffff909116908390839081106104ac576104ac6112f1565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526104da81611320565b9050610432565b505b92915050565b6040518060600160405280602c81526020016113c2602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526005602052604090205460ff1615610565576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206006546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa158015610699573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16146106f0576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061073557503373ffffffffffffffffffffffffffffffffffffffff8716148015906107355750333b155b1561076c576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610777600286610bbc565b156108495784600460006001601481819054906101000a900467ffffffffffffffff166107a390611358565b825467ffffffffffffffff9182166101009390930a838102920219161790915581526020808201929092526040908101600020805473ffffffffffffffffffffffffffffffffffffffff9485167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161790555191871682527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db4910160405180910390a15b505050505050565b610859610bde565b73ffffffffffffffffffffffffffffffffffffffff811660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60065460009060ff166108f1575060016108ff565b6108fc600285610c61565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461098c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6060610a146002610c90565b905090565b610a21610bde565b610a2c600282610c9d565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e191016108d1565b610ab4610bde565b805160068054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a91016108d1565b60065460009060ff16610b7c57506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205460ff1690565b610bb0610bde565b610bb981610cbf565b50565b60006108ff8373ffffffffffffffffffffffffffffffffffffffff8416610db4565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610983565b565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415156108ff565b606060006108ff83610e03565b60006108ff8373ffffffffffffffffffffffffffffffffffffffff8416610e5f565b3373ffffffffffffffffffffffffffffffffffffffff821603610d3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610983565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818152600183016020526040812054610dfb575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104e3565b5060006104e3565b606081600001805480602002602001604051908101604052809291908181526020018280548015610e5357602002820191906000526020600020905b815481526020019060010190808311610e3f575b50505050509050919050565b60008181526001830160205260408120548015610f48576000610e8360018361137f565b8554909150600090610e979060019061137f565b9050818114610efc576000866000018281548110610eb757610eb76112f1565b9060005260206000200154905080876000018481548110610eda57610eda6112f1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610f0d57610f0d611392565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104e3565b60009150506104e3565b803567ffffffffffffffff81168114610f6a57600080fd5b919050565b60008060408385031215610f8257600080fd5b610f8b83610f52565b9150610f9960208401610f52565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015610ff057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610fbe565b50909695505050505050565b600060208083528351808285015260005b818110156110295785810183015185820160400152820161100d565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f6a57600080fd5b600080600080600060a086880312156110a457600080fd5b6110ad86611068565b94506110bb60208701611068565b93506040860135925060608601359150608086013560ff811681146110df57600080fd5b809150509295509295909350565b6000602082840312156110ff57600080fd5b6108ff82611068565b60008060006040848603121561111d57600080fd5b61112684611068565b9250602084013567ffffffffffffffff8082111561114357600080fd5b818601915086601f83011261115757600080fd5b81358181111561116657600080fd5b87602082850101111561117857600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000604082840312156111cc57600080fd5b6040516040810181811067ffffffffffffffff82111715611216577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461122957600080fd5b815261123760208401611068565b60208201529392505050565b6000806040838503121561125657600080fd5b61125f83611068565b9150610f9960208401611068565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104e1576104e161126d565b67ffffffffffffffff8181168382160190808211156104e1576104e161126d565b808201808211156104e3576104e361126d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113515761135161126d565b5060010190565b600067ffffffffffffffff8083168181036113755761137561126d565b6001019392505050565b818103818111156104e3576104e361126d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", + Bin: "0x60806040523480156200001157600080fd5b506040516200162638038062001626833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160058054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b61132c80620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806382184c7b11610097578063a5e1d61d11610066578063a5e1d61d1461025a578063c3f909d41461026d578063cc7ebf49146102cc578063f2fde38b146102ed57600080fd5b806382184c7b1461019357806389f9a2c4146101a65780638da5cb5b146101b9578063a39b06e3146101e157600080fd5b806347663acb116100d357806347663acb1461014d5780636b14daf81461016057806379ba509714610183578063817ef62e1461018b57600080fd5b80630a8c9c24146100fa578063181f5a77146101235780633908c4d414610138575b600080fd5b61010d610108366004610ec8565b610300565b60405161011a9190610efb565b60405180910390f35b61012b610479565b60405161011a9190610f55565b61014b610146366004610fe5565b610495565b005b61014b61015b366004611046565b61075e565b61017361016e366004611061565b6107e9565b604051901515815260200161011a565b61014b610813565b61010d610915565b61014b6101a1366004611046565b610926565b61014b6101b4366004611113565b6109b9565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61024c6101ef36600461119c565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161011a565b610173610268366004611046565b610a74565b60408051808201825260008082526020918201528151808301835260055460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161011a565b6102d4610ab5565b60405167ffffffffffffffff909116815260200161011a565b61014b6102fb366004611046565b610ac1565b60608167ffffffffffffffff168367ffffffffffffffff16118061033657506103296002610ad5565b8267ffffffffffffffff16115b8061034857506103466002610ad5565b155b1561037f576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61038983836111f5565b610394906001611216565b67ffffffffffffffff1667ffffffffffffffff8111156103b6576103b66110e4565b6040519080825280602002602001820160405280156103df578160200160208202803683370190505b50905060005b6103ef84846111f5565b67ffffffffffffffff1681116104715761042a60016104188367ffffffffffffffff8816611237565b610422919061124a565b600290610adf565b82828151811061043c5761043c61125d565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261046a8161128c565b90506103e5565b505b92915050565b6040518060600160405280602c81526020016112f4602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602052604090205460ff16156104f5576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206005546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa158015610629573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610680576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff86161415806106c557503373ffffffffffffffffffffffffffffffffffffffff8716148015906106c55750333b155b156106fc576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610707600286610aeb565b156107565760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b610766610b0d565b73ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60055460009060ff166107fe5750600161080c565b610809600285610b90565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606109216002610bbf565b905090565b61092e610b0d565b610939600282610bcc565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e191016107de565b6109c1610b0d565b805160058054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a91016107de565b60055460009060ff16610a8957506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b60006109216002610ad5565b610ac9610b0d565b610ad281610bee565b50565b6000610473825490565b600061080c8383610ce3565b600061080c8373ffffffffffffffffffffffffffffffffffffffff8416610d0d565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610890565b565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561080c565b6060600061080c83610d5c565b600061080c8373ffffffffffffffffffffffffffffffffffffffff8416610db8565b3373ffffffffffffffffffffffffffffffffffffffff821603610c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610890565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610cfa57610cfa61125d565b9060005260206000200154905092915050565b6000818152600183016020526040812054610d5457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610473565b506000610473565b606081600001805480602002602001604051908101604052809291908181526020018280548015610dac57602002820191906000526020600020905b815481526020019060010190808311610d98575b50505050509050919050565b60008181526001830160205260408120548015610ea1576000610ddc60018361124a565b8554909150600090610df09060019061124a565b9050818114610e55576000866000018281548110610e1057610e1061125d565b9060005260206000200154905080876000018481548110610e3357610e3361125d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e6657610e666112c4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610473565b6000915050610473565b803567ffffffffffffffff81168114610ec357600080fd5b919050565b60008060408385031215610edb57600080fd5b610ee483610eab565b9150610ef260208401610eab565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015610f4957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f17565b50909695505050505050565b600060208083528351808285015260005b81811015610f8257858101830151858201604001528201610f66565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ec357600080fd5b600080600080600060a08688031215610ffd57600080fd5b61100686610fc1565b945061101460208701610fc1565b93506040860135925060608601359150608086013560ff8116811461103857600080fd5b809150509295509295909350565b60006020828403121561105857600080fd5b61080c82610fc1565b60008060006040848603121561107657600080fd5b61107f84610fc1565b9250602084013567ffffffffffffffff8082111561109c57600080fd5b818601915086601f8301126110b057600080fd5b8135818111156110bf57600080fd5b8760208285010111156110d157600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561112557600080fd5b6040516040810181811067ffffffffffffffff8211171561116f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461118257600080fd5b815261119060208401610fc1565b60208201529392505050565b600080604083850312156111af57600080fd5b6111b883610fc1565b9150610ef260208401610fc1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610471576104716111c6565b67ffffffffffffffff818116838216019080821115610471576104716111c6565b80820180821115610473576104736111c6565b81810381811115610473576104736111c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036112bd576112bd6111c6565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", } var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 508d517fe00..e2b3abbc9d3 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,6 +1,6 @@ GETH_VERSION: 1.13.8 functions: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db -functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 77e0180b0915b178f6acffacc6d04deb510b51ecc62b9d29770d271bc1eaf191 +functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin a705e4d8544d01798a504a70322d8c324779becd74ec4570527d929879898929 functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b From cdbced5c94ee03af2b560ea0d12a0f57bf190983 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Mon, 8 Jan 2024 14:47:33 +0100 Subject: [PATCH 05/23] feat: implement orm level for allowlist --- .../gateway/handlers/functions/allowlist.go | 2 +- .../gateway/handlers/functions/mocks/orm.go | 4 +- .../gateway/handlers/functions/orm.go | 35 +++++++- .../gateway/handlers/functions/orm_test.go | 79 +++++++++++++++++++ 4 files changed, 113 insertions(+), 7 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index d30642ccd95..2e2dd1330b3 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -233,7 +233,7 @@ func (a *onchainAllowlist) update(addrList []common.Address) { func (a *onchainAllowlist) updateCache(addrList []common.Address) { for id, addr := range addrList { - if err := a.orm.UpsertAllowedSender(int64(id), addr); err != nil { + if err := a.orm.UpsertAllowedSender(uint64(id), addr); err != nil { a.lggr.Errorf("failed to update cache: %w", err) } } diff --git a/core/services/gateway/handlers/functions/mocks/orm.go b/core/services/gateway/handlers/functions/mocks/orm.go index d0b8dc6b4f9..06a791d6d23 100644 --- a/core/services/gateway/handlers/functions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/mocks/orm.go @@ -90,7 +90,7 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]fu } // UpsertAllowedSender provides a mock function with given fields: id, allowedSender, qopts -func (_m *ORM) UpsertAllowedSender(id int64, allowedSender common.Address, qopts ...pg.QOpt) error { +func (_m *ORM) UpsertAllowedSender(id uint64, allowedSender common.Address, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) for _i := range qopts { _va[_i] = qopts[_i] @@ -105,7 +105,7 @@ func (_m *ORM) UpsertAllowedSender(id int64, allowedSender common.Address, qopts } var r0 error - if rf, ok := ret.Get(0).(func(int64, common.Address, ...pg.QOpt) error); ok { + if rf, ok := ret.Get(0).(func(uint64, common.Address, ...pg.QOpt) error); ok { r0 = rf(id, allowedSender, qopts...) } else { r0 = ret.Error(0) diff --git a/core/services/gateway/handlers/functions/orm.go b/core/services/gateway/handlers/functions/orm.go index 8d351969463..0c96d3d14d2 100644 --- a/core/services/gateway/handlers/functions/orm.go +++ b/core/services/gateway/handlers/functions/orm.go @@ -20,8 +20,9 @@ import ( type ORM interface { GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSubscription, error) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error + GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) - UpsertAllowedSender(id int64, allowedSender common.Address, qopts ...pg.QOpt) error + UpsertAllowedSender(id uint64, allowedSender common.Address, qopts ...pg.QOpt) error } type orm struct { @@ -135,9 +136,35 @@ func (cs *cachedSubscriptionRow) encode() CachedSubscription { } func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { - return nil, nil + var address []common.Address + stmt := fmt.Sprintf(` + SELECT allowed_address + FROM %s + WHERE router_contract_address = $1 + ORDER BY id ASC + OFFSET $2 + LIMIT $3; + `, allowlistTableName) + err := o.q.WithOpts(qopts...).Select(&address, stmt, o.routerContractAddress, offset, limit) + if err != nil { + return address, err + } + + return address, nil } -func (o *orm) UpsertAllowedSender(id int64, allowedSender common.Address, qopts ...pg.QOpt) error { - return nil +func (o *orm) UpsertAllowedSender(id uint64, allowedSender common.Address, qopts ...pg.QOpt) error { + stmt := fmt.Sprintf(` + INSERT INTO %s (id, allowed_address, router_contract_address) + VALUES ($1,$2,$3) ON CONFLICT (id, router_contract_address) DO UPDATE + SET allowed_address=$2, router_contract_address=$3;`, allowlistTableName) + + _, err := o.q.WithOpts(qopts...).Exec( + stmt, + id, + allowedSender, + o.routerContractAddress, + ) + + return err } diff --git a/core/services/gateway/handlers/functions/orm_test.go b/core/services/gateway/handlers/functions/orm_test.go index 37ec24ea0b1..13411d95f0b 100644 --- a/core/services/gateway/handlers/functions/orm_test.go +++ b/core/services/gateway/handlers/functions/orm_test.go @@ -51,6 +51,16 @@ func createSubscriptions(t *testing.T, orm functions.ORM, amount int) []function return cachedSubscriptions } +func createAllowedSenders(t *testing.T, orm functions.ORM, amount int) []common.Address { + cachedAllowedSenders := make([]common.Address, 0) + for i := amount; i > 0; i-- { + address := testutils.NewAddress() + cachedAllowedSenders = append(cachedAllowedSenders, address) + err := orm.UpsertAllowedSender(uint64(i), address) + require.NoError(t, err) + } + return cachedAllowedSenders +} func TestORM_GetSubscriptions(t *testing.T) { t.Parallel() t.Run("fetch first page", func(t *testing.T) { @@ -230,6 +240,75 @@ func TestORM_UpsertSubscription(t *testing.T) { }) } +func TestORM_GetAllowedSenders(t *testing.T) { + t.Parallel() + t.Run("fetch first page", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + cachedAllowedSenders := createAllowedSenders(t, orm, 2) + results, err := orm.GetAllowedSenders(0, 1) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, cachedAllowedSenders[1], results[0]) + }) + + t.Run("fetch second page", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + cachedAllowedSenders := createAllowedSenders(t, orm, 2) + results, err := orm.GetAllowedSenders(1, 5) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, cachedAllowedSenders[0], results[0]) + }) +} + +func TestORM_UpsertAllowedSender(t *testing.T) { + t.Parallel() + + type allowedSender struct { + id uint64 + address common.Address + } + + t.Run("create an allowed sender", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + expected := allowedSender{uint64(1), testutils.NewAddress()} + err = orm.UpsertAllowedSender(expected.id, expected.address) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 1) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, expected.address, results[0]) + }) + + t.Run("update an allowed sender", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + + expectedUpdated := allowedSender{uint64(1), testutils.NewAddress()} + err = orm.UpsertAllowedSender(expectedUpdated.id, expectedUpdated.address) + require.NoError(t, err) + + expectedNotUpdated := allowedSender{uint64(2), testutils.NewAddress()} + err = orm.UpsertAllowedSender(expectedNotUpdated.id, expectedNotUpdated.address) + require.NoError(t, err) + + // update the address + expectedUpdated.address = testutils.NewAddress() + err = orm.UpsertAllowedSender(expectedUpdated.id, expectedUpdated.address) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 5) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, expectedNotUpdated.address, results[1]) + require.Equal(t, expectedUpdated.address, results[0]) + }) +} + func Test_NewORM(t *testing.T) { t.Run("OK-create_ORM", func(t *testing.T) { _, err := functions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress()) From 98062b4433df4f57f0df8d4f6d9710a533b98583 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Mon, 8 Jan 2024 16:22:49 +0100 Subject: [PATCH 06/23] fix: fix iteration loop and add tests --- .../accessControl/TermsOfServiceAllowList.sol | 2 +- .../gateway/handlers/functions/allowlist.go | 14 ++-- .../handlers/functions/allowlist_test.go | 72 +++++++++++++++++-- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol index ca58bf0216a..6185c516dd0 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol @@ -108,7 +108,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, } /// @dev WARNING: getAllowedSendersInRange uses EnumerableSet .length() and .at() methods to iterate over the list - /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. + /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. /// Evaluate if eventual consistency will satisfy your usecase before using it. function getAllowedSendersInRange( uint64 allowedSenderIdStart, diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 2e2dd1330b3..441cf3e7a6b 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -187,7 +187,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b return errors.Wrap(err, "unexpected error during functions_allow_list.NewTermsOfServiceAllowList") } - idEnd, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ + count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, Context: ctx, @@ -196,9 +196,13 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b return errors.Wrap(err, "unexpected error during functions_allow_list.GetAllowedSendersCount") } - idStart := uint64(0) allowedSenderList := make([]common.Address, 0) - for { + for idStart := uint64(0); idStart < count; idStart += uint64(a.config.CacheBatchSize) { + idEnd := idStart + uint64(a.config.CacheBatchSize) + if idEnd > count { + idEnd = count + } + allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, @@ -210,11 +214,9 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b allowedSenderList = append(allowedSenderList, allowedSendersBatch...) - if len(allowedSendersBatch) < int(a.config.CacheBatchSize) { + if idEnd == count { break } - - idStart += uint64(a.config.CacheBatchSize) } a.update(allowedSenderList) diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index 6c436494c3e..8c525173803 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -50,8 +50,8 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("UpsertAllowedSender", int64(0), common.HexToAddress(addr1)).Return(nil) - orm.On("UpsertAllowedSender", int64(1), common.HexToAddress(addr2)).Return(nil) + orm.On("UpsertAllowedSender", uint64(0), common.HexToAddress(addr1)).Return(nil) + orm.On("UpsertAllowedSender", uint64(1), common.HexToAddress(addr2)).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -103,8 +103,8 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { orm := fmocks.NewORM(t) orm.On("GetAllowedSenders", uint(0), uint(100)).Return([]common.Address{}, nil) - orm.On("UpsertAllowedSender", int64(0), common.HexToAddress(addr1)).Return(nil) - orm.On("UpsertAllowedSender", int64(1), common.HexToAddress(addr2)).Return(nil) + orm.On("UpsertAllowedSender", uint64(0), common.HexToAddress(addr1)).Return(nil) + orm.On("UpsertAllowedSender", uint64(1), common.HexToAddress(addr2)).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -119,3 +119,67 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) } +func TestAllowlist_UpdateFromContract(t *testing.T) { + t.Parallel() + + t.Run("OK-iterate_over_list_of_allowed_senders", func(t *testing.T) { + ctx, cancel := context.WithCancel(testutils.Context(t)) + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + cancel() + }).Return(sampleEncodedAllowlist(t), nil) + config := functions.OnchainAllowlistConfig{ + ContractAddress: common.Address{}, + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 1, + UpdateTimeoutSec: 1, + CacheBatchSize: 2, + } + + orm := fmocks.NewORM(t) + orm.On("UpsertAllowedSender", uint64(0), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(1), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(2), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(3), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(4), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(5), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(6), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(7), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(8), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(9), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(10), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(11), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(12), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(13), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(14), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(15), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(16), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(17), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(18), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(19), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(20), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(21), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(22), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(23), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(24), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(25), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(26), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(27), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(28), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(29), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(30), common.HexToAddress(addr1)).Once().Return(nil) + orm.On("UpsertAllowedSender", uint64(31), common.HexToAddress(addr2)).Once().Return(nil) + + allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + require.NoError(t, err) + + err = allowlist.UpdateFromContract(ctx) + require.NoError(t, err) + + gomega.NewGomegaWithT(t).Eventually(func() bool { + return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + }) +} From 6de74c84d4b86ae39acce3db1b51fbf43e10e926 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Wed, 10 Jan 2024 14:35:31 +0100 Subject: [PATCH 07/23] fix: correct var naming, zero indexing array, doc --- .../gas-snapshots/functions.gas-snapshot | 24 +++++++------- .../accessControl/TermsOfServiceAllowList.sol | 18 +++++------ .../interfaces/ITermsOfServiceAllowList.sol | 3 ++ .../FunctionsTermsOfServiceAllowList.t.sol | 32 +++++++++++++++++-- .../functions_allow_list.go | 18 +++++------ ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../gateway/handlers/functions/allowlist.go | 14 +++----- 7 files changed, 68 insertions(+), 43 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index 7cc9dc04223..a7ddb4cf6c5 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,12 +1,12 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14751886) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14751864) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14751880) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14763300) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14763277) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14763249) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14763200) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14763189) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14763233) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14749683) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14749661) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14749677) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14761097) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14761074) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14761046) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14760997) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14760986) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14761030) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) @@ -207,8 +207,10 @@ FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 51848) FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12209) FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19265) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16557) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20523) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12128365) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16560) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13279) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20426) FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15751) FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11637) FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15947) diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol index 6185c516dd0..ba31cd287a5 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol @@ -107,24 +107,22 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, return uint64(s_allowedSenders.length()); } - /// @dev WARNING: getAllowedSendersInRange uses EnumerableSet .length() and .at() methods to iterate over the list - /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. - /// Evaluate if eventual consistency will satisfy your usecase before using it. + /// @inheritdoc ITermsOfServiceAllowList function getAllowedSendersInRange( - uint64 allowedSenderIdStart, - uint64 allowedSenderIdEnd + uint64 allowedSenderIdxStart, + uint64 allowedSenderIdxEnd ) external view override returns (address[] memory allowedSenders) { if ( - allowedSenderIdStart > allowedSenderIdEnd || - allowedSenderIdEnd > s_allowedSenders.length() || + allowedSenderIdxStart > allowedSenderIdxEnd || + allowedSenderIdxEnd >= s_allowedSenders.length() || s_allowedSenders.length() == 0 ) { revert InvalidCalldata(); } - allowedSenders = new address[]((allowedSenderIdEnd - allowedSenderIdStart) + 1); - for (uint256 i = 0; i <= allowedSenderIdEnd - allowedSenderIdStart; ++i) { - allowedSenders[i] = s_allowedSenders.at(uint256(allowedSenderIdStart + i - 1)); + allowedSenders = new address[]((allowedSenderIdxEnd - allowedSenderIdxStart) + 1); + for (uint256 i = 0; i <= allowedSenderIdxEnd - allowedSenderIdxStart; ++i) { + allowedSenders[i] = s_allowedSenders.at(uint256(allowedSenderIdxStart + i)); } return allowedSenders; diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol index de1982b3248..51c0ca34533 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol @@ -27,6 +27,9 @@ interface ITermsOfServiceAllowList { function getAllowedSendersCount() external view returns (uint64); /// @notice Retrieve a list of allowed senders using an inclusive range + /// @dev WARNING: getAllowedSendersInRange uses EnumerableSet .length() and .at() methods to iterate over the list + /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. + /// Evaluate if eventual consistency will satisfy your usecase before using it. /// @param allowedSenderIdStart - the ID of the allowed sender to start the range at /// @param allowedSenderIdEnd - the ID of the allowed sender to end the range at /// @return allowedSenders - all allowed addresses diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol index 81e2621e40c..b9b2cb8efc1 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol @@ -257,7 +257,33 @@ contract FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange is FunctionsO address[] memory expectedSenders = new address[](1); expectedSenders[0] = OWNER_ADDRESS; - assertEq(s_termsOfServiceAllowList.getAllowedSendersInRange(1, 1), expectedSenders); + assertEq(s_termsOfServiceAllowList.getAllowedSendersInRange(0, 0), expectedSenders); + } + + function test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() public { + // setup a new empty s_termsOfServiceAllowList + FunctionsRoutesSetup.setUp(); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint64 AllowedSendersCount = s_termsOfServiceAllowList.getAllowedSendersCount(); + uint64 expected = 0; + assertEq(AllowedSendersCount, expected); + + vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); + s_termsOfServiceAllowList.getAllowedSendersInRange(0, 0); + } + + function test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); + + s_termsOfServiceAllowList.getAllowedSendersInRange(1, 0); } function test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() public { @@ -265,9 +291,9 @@ contract FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange is FunctionsO vm.stopPrank(); vm.startPrank(STRANGER_ADDRESS); - uint64 lastAllowedSenderId = s_termsOfServiceAllowList.getAllowedSendersCount(); + uint64 AllowedSendersCount = s_termsOfServiceAllowList.getAllowedSendersCount(); vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); - s_termsOfServiceAllowList.getAllowedSendersInRange(1, lastAllowedSenderId + 1); + s_termsOfServiceAllowList.getAllowedSendersInRange(1, AllowedSendersCount + 1); } } diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go index 314708ddabb..9d2a2c88621 100644 --- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go +++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go @@ -36,8 +36,8 @@ type TermsOfServiceAllowListConfig struct { } var TermsOfServiceAllowListMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200162638038062001626833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160058054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b61132c80620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806382184c7b11610097578063a5e1d61d11610066578063a5e1d61d1461025a578063c3f909d41461026d578063cc7ebf49146102cc578063f2fde38b146102ed57600080fd5b806382184c7b1461019357806389f9a2c4146101a65780638da5cb5b146101b9578063a39b06e3146101e157600080fd5b806347663acb116100d357806347663acb1461014d5780636b14daf81461016057806379ba509714610183578063817ef62e1461018b57600080fd5b80630a8c9c24146100fa578063181f5a77146101235780633908c4d414610138575b600080fd5b61010d610108366004610ec8565b610300565b60405161011a9190610efb565b60405180910390f35b61012b610479565b60405161011a9190610f55565b61014b610146366004610fe5565b610495565b005b61014b61015b366004611046565b61075e565b61017361016e366004611061565b6107e9565b604051901515815260200161011a565b61014b610813565b61010d610915565b61014b6101a1366004611046565b610926565b61014b6101b4366004611113565b6109b9565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61024c6101ef36600461119c565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161011a565b610173610268366004611046565b610a74565b60408051808201825260008082526020918201528151808301835260055460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161011a565b6102d4610ab5565b60405167ffffffffffffffff909116815260200161011a565b61014b6102fb366004611046565b610ac1565b60608167ffffffffffffffff168367ffffffffffffffff16118061033657506103296002610ad5565b8267ffffffffffffffff16115b8061034857506103466002610ad5565b155b1561037f576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61038983836111f5565b610394906001611216565b67ffffffffffffffff1667ffffffffffffffff8111156103b6576103b66110e4565b6040519080825280602002602001820160405280156103df578160200160208202803683370190505b50905060005b6103ef84846111f5565b67ffffffffffffffff1681116104715761042a60016104188367ffffffffffffffff8816611237565b610422919061124a565b600290610adf565b82828151811061043c5761043c61125d565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261046a8161128c565b90506103e5565b505b92915050565b6040518060600160405280602c81526020016112f4602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602052604090205460ff16156104f5576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206005546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa158015610629573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610680576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff86161415806106c557503373ffffffffffffffffffffffffffffffffffffffff8716148015906106c55750333b155b156106fc576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610707600286610aeb565b156107565760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b610766610b0d565b73ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60055460009060ff166107fe5750600161080c565b610809600285610b90565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606109216002610bbf565b905090565b61092e610b0d565b610939600282610bcc565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e191016107de565b6109c1610b0d565b805160058054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a91016107de565b60055460009060ff16610a8957506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b60006109216002610ad5565b610ac9610b0d565b610ad281610bee565b50565b6000610473825490565b600061080c8383610ce3565b600061080c8373ffffffffffffffffffffffffffffffffffffffff8416610d0d565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b8e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610890565b565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561080c565b6060600061080c83610d5c565b600061080c8373ffffffffffffffffffffffffffffffffffffffff8416610db8565b3373ffffffffffffffffffffffffffffffffffffffff821603610c6d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610890565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610cfa57610cfa61125d565b9060005260206000200154905092915050565b6000818152600183016020526040812054610d5457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610473565b506000610473565b606081600001805480602002602001604051908101604052809291908181526020018280548015610dac57602002820191906000526020600020905b815481526020019060010190808311610d98575b50505050509050919050565b60008181526001830160205260408120548015610ea1576000610ddc60018361124a565b8554909150600090610df09060019061124a565b9050818114610e55576000866000018281548110610e1057610e1061125d565b9060005260206000200154905080876000018481548110610e3357610e3361125d565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e6657610e666112c4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610473565b6000915050610473565b803567ffffffffffffffff81168114610ec357600080fd5b919050565b60008060408385031215610edb57600080fd5b610ee483610eab565b9150610ef260208401610eab565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015610f4957835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f17565b50909695505050505050565b600060208083528351808285015260005b81811015610f8257858101830151858201604001528201610f66565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ec357600080fd5b600080600080600060a08688031215610ffd57600080fd5b61100686610fc1565b945061101460208701610fc1565b93506040860135925060608601359150608086013560ff8116811461103857600080fd5b809150509295509295909350565b60006020828403121561105857600080fd5b61080c82610fc1565b60008060006040848603121561107657600080fd5b61107f84610fc1565b9250602084013567ffffffffffffffff8082111561109c57600080fd5b818601915086601f8301126110b057600080fd5b8135818111156110bf57600080fd5b8760208285010111156110d157600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561112557600080fd5b6040516040810181811067ffffffffffffffff8211171561116f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461118257600080fd5b815261119060208401610fc1565b60208201529392505050565b600080604083850312156111af57600080fd5b6111b883610fc1565b9150610ef260208401610fc1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610471576104716111c6565b67ffffffffffffffff818116838216019080821115610471576104716111c6565b80820180821115610473576104736111c6565b81810381811115610473576104736111c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036112bd576112bd6111c6565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b506040516200161b3803806200161b833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160058054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b61132180620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806382184c7b11610097578063a5e1d61d11610066578063a5e1d61d1461025a578063c3f909d41461026d578063cc7ebf49146102cc578063f2fde38b146102ed57600080fd5b806382184c7b1461019357806389f9a2c4146101a65780638da5cb5b146101b9578063a39b06e3146101e157600080fd5b806347663acb116100d357806347663acb1461014d5780636b14daf81461016057806379ba509714610183578063817ef62e1461018b57600080fd5b80630a8c9c24146100fa578063181f5a77146101235780633908c4d414610138575b600080fd5b61010d610108366004610ebd565b610300565b60405161011a9190610ef0565b60405180910390f35b61012b61046e565b60405161011a9190610f4a565b61014b610146366004610fda565b61048a565b005b61014b61015b36600461103b565b610753565b61017361016e366004611056565b6107de565b604051901515815260200161011a565b61014b610808565b61010d61090a565b61014b6101a136600461103b565b61091b565b61014b6101b4366004611108565b6109ae565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61024c6101ef366004611191565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161011a565b61017361026836600461103b565b610a69565b60408051808201825260008082526020918201528151808301835260055460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161011a565b6102d4610aaa565b60405167ffffffffffffffff909116815260200161011a565b61014b6102fb36600461103b565b610ab6565b60608167ffffffffffffffff168367ffffffffffffffff16118061033757506103296002610aca565b8267ffffffffffffffff1610155b8061034957506103476002610aca565b155b15610380576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61038a83836111ea565b61039590600161120b565b67ffffffffffffffff1667ffffffffffffffff8111156103b7576103b76110d9565b6040519080825280602002602001820160405280156103e0578160200160208202803683370190505b50905060005b6103f084846111ea565b67ffffffffffffffff1681116104665761041f6104178267ffffffffffffffff871661122c565b600290610ad4565b8282815181106104315761043161123f565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261045f8161126e565b90506103e6565b505b92915050565b6040518060600160405280602c81526020016112e9602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602052604090205460ff16156104ea576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206005546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa15801561061e573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610675576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff86161415806106ba57503373ffffffffffffffffffffffffffffffffffffffff8716148015906106ba5750333b155b156106f1576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106fc600286610ae0565b1561074b5760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b61075b610b02565b73ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60055460009060ff166107f357506001610801565b6107fe600285610b85565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461088e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606109166002610bb4565b905090565b610923610b02565b61092e600282610bc1565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e191016107d3565b6109b6610b02565b805160058054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a91016107d3565b60055460009060ff16610a7e57506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b60006109166002610aca565b610abe610b02565b610ac781610be3565b50565b6000610468825490565b60006108018383610cd8565b60006108018373ffffffffffffffffffffffffffffffffffffffff8416610d02565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610885565b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610801565b6060600061080183610d51565b60006108018373ffffffffffffffffffffffffffffffffffffffff8416610dad565b3373ffffffffffffffffffffffffffffffffffffffff821603610c62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610885565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610cef57610cef61123f565b9060005260206000200154905092915050565b6000818152600183016020526040812054610d4957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610468565b506000610468565b606081600001805480602002602001604051908101604052809291908181526020018280548015610da157602002820191906000526020600020905b815481526020019060010190808311610d8d575b50505050509050919050565b60008181526001830160205260408120548015610e96576000610dd16001836112a6565b8554909150600090610de5906001906112a6565b9050818114610e4a576000866000018281548110610e0557610e0561123f565b9060005260206000200154905080876000018481548110610e2857610e2861123f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e5b57610e5b6112b9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610468565b6000915050610468565b803567ffffffffffffffff81168114610eb857600080fd5b919050565b60008060408385031215610ed057600080fd5b610ed983610ea0565b9150610ee760208401610ea0565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015610f3e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f0c565b50909695505050505050565b600060208083528351808285015260005b81811015610f7757858101830151858201604001528201610f5b565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610eb857600080fd5b600080600080600060a08688031215610ff257600080fd5b610ffb86610fb6565b945061100960208701610fb6565b93506040860135925060608601359150608086013560ff8116811461102d57600080fd5b809150509295509295909350565b60006020828403121561104d57600080fd5b61080182610fb6565b60008060006040848603121561106b57600080fd5b61107484610fb6565b9250602084013567ffffffffffffffff8082111561109157600080fd5b818601915086601f8301126110a557600080fd5b8135818111156110b457600080fd5b8760208285010111156110c657600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561111a57600080fd5b6040516040810181811067ffffffffffffffff82111715611164577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461117757600080fd5b815261118560208401610fb6565b60208201529392505050565b600080604083850312156111a457600080fd5b6111ad83610fb6565b9150610ee760208401610fb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610466576104666111bb565b67ffffffffffffffff818116838216019080821115610466576104666111bb565b80820180821115610468576104686111bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361129f5761129f6111bb565b5060010190565b81810381811115610468576104686111bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", } var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI @@ -220,9 +220,9 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllowed return _TermsOfServiceAllowList.Contract.GetAllowedSendersCount(&_TermsOfServiceAllowList.CallOpts) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) { +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdxStart uint64, allowedSenderIdxEnd uint64) ([]common.Address, error) { var out []interface{} - err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getAllowedSendersInRange", allowedSenderIdStart, allowedSenderIdEnd) + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getAllowedSendersInRange", allowedSenderIdxStart, allowedSenderIdxEnd) if err != nil { return *new([]common.Address), err @@ -234,12 +234,12 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetAllowedSenders } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetAllowedSendersInRange(allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) { - return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdStart, allowedSenderIdEnd) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetAllowedSendersInRange(allowedSenderIdxStart uint64, allowedSenderIdxEnd uint64) ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdxStart, allowedSenderIdxEnd) } -func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllowedSendersInRange(allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) { - return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdStart, allowedSenderIdEnd) +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllowedSendersInRange(allowedSenderIdxStart uint64, allowedSenderIdxEnd uint64) ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdxStart, allowedSenderIdxEnd) } func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) { @@ -1239,7 +1239,7 @@ type TermsOfServiceAllowListInterface interface { GetAllowedSendersCount(opts *bind.CallOpts) (uint64, error) - GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdStart uint64, allowedSenderIdEnd uint64) ([]common.Address, error) + GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdxStart uint64, allowedSenderIdxEnd uint64) ([]common.Address, error) GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index e2b3abbc9d3..7fba72d7758 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,6 +1,6 @@ GETH_VERSION: 1.13.8 functions: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db -functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin a705e4d8544d01798a504a70322d8c324779becd74ec4570527d929879898929 +functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 685b10a36b86a82eff858ba45d71f7bb5ea168fea0e5da3c7c5c2d17dfe72baa functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 441cf3e7a6b..686c429707d 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -197,26 +197,22 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList := make([]common.Address, 0) - for idStart := uint64(0); idStart < count; idStart += uint64(a.config.CacheBatchSize) { - idEnd := idStart + uint64(a.config.CacheBatchSize) - if idEnd > count { - idEnd = count + for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.CacheBatchSize) { + idxEnd := idxStart + uint64(a.config.CacheBatchSize) + if idxEnd >= count { + idxEnd = count - 1 } allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, Context: ctx, - }, idStart, idEnd) + }, idxStart, idxEnd) if err != nil { return errors.Wrap(err, "error calling GetAllowedSendersInRange") } allowedSenderList = append(allowedSenderList, allowedSendersBatch...) - - if idEnd == count { - break - } } a.update(allowedSenderList) From 7f72ef3f02d981b23d221fd4465e9c9ac7b6ad19 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Wed, 10 Jan 2024 16:00:06 +0100 Subject: [PATCH 08/23] chore: rename cache to stored, split batchSize onchain vs stored --- .../gateway/handlers/functions/allowlist.go | 47 ++++++++++++------- .../handlers/functions/allowlist_test.go | 13 ++--- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 686c429707d..b5fda0d2479 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -22,7 +22,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -const defaultAllowlistCacheBatchSize = 100 +const ( + defaultStoredAllowlistBatchSize = 100 + defaultOnchainAllowlistBatchSize = 100 +) type OnchainAllowlistConfig struct { // ContractAddress is required @@ -30,9 +33,10 @@ type OnchainAllowlistConfig struct { ContractVersion uint32 `json:"contractVersion"` BlockConfirmations uint `json:"blockConfirmations"` // UpdateFrequencySec can be zero to disable periodic updates - UpdateFrequencySec uint `json:"updateFrequencySec"` - UpdateTimeoutSec uint `json:"updateTimeoutSec"` - CacheBatchSize uint `json:"cacheBatchSize"` + UpdateFrequencySec uint `json:"updateFrequencySec"` + UpdateTimeoutSec uint `json:"updateTimeoutSec"` + StoredAllowlistBatchSize uint `json:"storedAllowlistBatchSize"` + OnchainAllowlistBatchSize uint `json:"onchainAllowlistBatchSize"` } // OnchainAllowlist maintains an allowlist of addresses fetched from the blockchain (EVM-only). @@ -73,10 +77,16 @@ func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, return nil, fmt.Errorf("unsupported contract version %d", config.ContractVersion) } - // if CacheBatchSize is not specified used the default value - if config.CacheBatchSize == 0 { - lggr.Info("CacheBatchSize not specified, using default size: ", defaultAllowlistCacheBatchSize) - config.CacheBatchSize = defaultAllowlistCacheBatchSize + // if StoredAllowlistBatchSize is not specified used the default value + if config.StoredAllowlistBatchSize == 0 { + lggr.Info("StoredAllowlistBatchSize not specified, using default size: ", defaultStoredAllowlistBatchSize) + config.StoredAllowlistBatchSize = defaultStoredAllowlistBatchSize + } + + // if OnchainAllowlistBatchSize is not specified used the default value + if config.OnchainAllowlistBatchSize == 0 { + lggr.Info("OnchainAllowlistBatchSize not specified, using default size: ", defaultOnchainAllowlistBatchSize) + config.OnchainAllowlistBatchSize = defaultOnchainAllowlistBatchSize } contractV1, err := functions_router.NewFunctionsRouter(config.ContractAddress, client) @@ -113,7 +123,7 @@ func (a *onchainAllowlist) Start(ctx context.Context) error { cancel() } - a.loadCachedAllowedList() + a.loadStoredAllowedSenderList() a.closeWait.Add(1) go func() { @@ -197,8 +207,8 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList := make([]common.Address, 0) - for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.CacheBatchSize) { - idxEnd := idxStart + uint64(a.config.CacheBatchSize) + for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { + idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) if idxEnd >= count { idxEnd = count - 1 } @@ -216,7 +226,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } a.update(allowedSenderList) - a.updateCache(allowedSenderList) + a.updateStoredAllowedSenderList(allowedSenderList) return nil } @@ -229,29 +239,30 @@ func (a *onchainAllowlist) update(addrList []common.Address) { a.lggr.Infow("allowlist updated successfully", "len", len(addrList)) } -func (a *onchainAllowlist) updateCache(addrList []common.Address) { +func (a *onchainAllowlist) updateStoredAllowedSenderList(addrList []common.Address) { for id, addr := range addrList { if err := a.orm.UpsertAllowedSender(uint64(id), addr); err != nil { - a.lggr.Errorf("failed to update cache: %w", err) + a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) } } } -func (a *onchainAllowlist) loadCachedAllowedList() { +func (a *onchainAllowlist) loadStoredAllowedSenderList() { allowedList := make([]common.Address, 0) offset := uint(0) for { - asBatch, err := a.orm.GetAllowedSenders(offset, a.config.CacheBatchSize) + asBatch, err := a.orm.GetAllowedSenders(offset, a.config.StoredAllowlistBatchSize) if err != nil { + a.lggr.Errorf("failed to get stored allowed senders: %w", err) break } allowedList = append(allowedList, asBatch...) - if len(asBatch) != int(a.config.CacheBatchSize) { + if len(asBatch) != int(a.config.StoredAllowlistBatchSize) { break } - offset += a.config.CacheBatchSize + offset += a.config.StoredAllowlistBatchSize } a.update(allowedList) diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index 8c525173803..3d4a071b01c 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -130,12 +130,13 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { cancel() }).Return(sampleEncodedAllowlist(t), nil) config := functions.OnchainAllowlistConfig{ - ContractAddress: common.Address{}, - ContractVersion: 1, - BlockConfirmations: 1, - UpdateFrequencySec: 1, - UpdateTimeoutSec: 1, - CacheBatchSize: 2, + ContractAddress: common.Address{}, + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 1, + UpdateTimeoutSec: 1, + StoredAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 2, } orm := fmocks.NewORM(t) From 80e116dde38fa5c1d170d33e3fb2bd05ea0d28ef Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Thu, 11 Jan 2024 14:39:30 +0100 Subject: [PATCH 09/23] fix: remove id from allowlist primary key, use it only for ordering --- .../gateway/handlers/functions/allowlist.go | 4 +- .../handlers/functions/allowlist_test.go | 72 +++++++++---------- .../gateway/handlers/functions/mocks/orm.go | 50 ++++++------- .../gateway/handlers/functions/orm.go | 28 ++++---- .../gateway/handlers/functions/orm_test.go | 71 ++++++++---------- ...wlist.sql => 0220_functions_allowlist.sql} | 4 +- 6 files changed, 111 insertions(+), 118 deletions(-) rename core/store/migrate/migrations/{0216_functions_allowlist.sql => 0220_functions_allowlist.sql} (80%) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index b5fda0d2479..5aa55cb2488 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -240,8 +240,8 @@ func (a *onchainAllowlist) update(addrList []common.Address) { } func (a *onchainAllowlist) updateStoredAllowedSenderList(addrList []common.Address) { - for id, addr := range addrList { - if err := a.orm.UpsertAllowedSender(uint64(id), addr); err != nil { + for _, addr := range addrList { + if err := a.orm.CreateAllowedSender(addr); err != nil { a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) } } diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index 3d4a071b01c..f96dc2b2bfb 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -50,8 +50,8 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("UpsertAllowedSender", uint64(0), common.HexToAddress(addr1)).Return(nil) - orm.On("UpsertAllowedSender", uint64(1), common.HexToAddress(addr2)).Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -103,8 +103,8 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { orm := fmocks.NewORM(t) orm.On("GetAllowedSenders", uint(0), uint(100)).Return([]common.Address{}, nil) - orm.On("UpsertAllowedSender", uint64(0), common.HexToAddress(addr1)).Return(nil) - orm.On("UpsertAllowedSender", uint64(1), common.HexToAddress(addr2)).Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -140,38 +140,38 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("UpsertAllowedSender", uint64(0), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(1), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(2), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(3), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(4), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(5), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(6), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(7), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(8), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(9), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(10), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(11), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(12), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(13), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(14), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(15), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(16), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(17), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(18), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(19), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(20), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(21), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(22), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(23), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(24), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(25), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(26), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(27), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(28), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(29), common.HexToAddress(addr2)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(30), common.HexToAddress(addr1)).Once().Return(nil) - orm.On("UpsertAllowedSender", uint64(31), common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) + orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) diff --git a/core/services/gateway/handlers/functions/mocks/orm.go b/core/services/gateway/handlers/functions/mocks/orm.go index 06a791d6d23..dbc9f18c403 100644 --- a/core/services/gateway/handlers/functions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/mocks/orm.go @@ -15,6 +15,31 @@ type ORM struct { mock.Mock } +// CreateAllowedSender provides a mock function with given fields: allowedSender, qopts +func (_m *ORM) CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, allowedSender) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for CreateAllowedSender") + } + + var r0 error + if rf, ok := ret.Get(0).(func(common.Address, ...pg.QOpt) error); ok { + r0 = rf(allowedSender, qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // GetAllowedSenders provides a mock function with given fields: offset, limit, qopts func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { _va := make([]interface{}, len(qopts)) @@ -89,31 +114,6 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]fu return r0, r1 } -// UpsertAllowedSender provides a mock function with given fields: id, allowedSender, qopts -func (_m *ORM) UpsertAllowedSender(id uint64, allowedSender common.Address, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, id, allowedSender) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for UpsertAllowedSender") - } - - var r0 error - if rf, ok := ret.Get(0).(func(uint64, common.Address, ...pg.QOpt) error); ok { - r0 = rf(id, allowedSender, qopts...) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // UpsertSubscription provides a mock function with given fields: subscription, qopts func (_m *ORM) UpsertSubscription(subscription functions.CachedSubscription, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) diff --git a/core/services/gateway/handlers/functions/orm.go b/core/services/gateway/handlers/functions/orm.go index 0c96d3d14d2..c47b52d3b7f 100644 --- a/core/services/gateway/handlers/functions/orm.go +++ b/core/services/gateway/handlers/functions/orm.go @@ -16,17 +16,17 @@ import ( ) //go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore - type ORM interface { GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSubscription, error) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) - UpsertAllowedSender(id uint64, allowedSender common.Address, qopts ...pg.QOpt) error + CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOpt) error } type orm struct { q pg.Q + lggr logger.Logger routerContractAddress common.Address } @@ -58,6 +58,7 @@ func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, routerContractAddre return &orm{ q: pg.NewQ(db, lggr, cfg), + lggr: lggr, routerContractAddress: routerContractAddress, }, nil } @@ -136,7 +137,7 @@ func (cs *cachedSubscriptionRow) encode() CachedSubscription { } func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { - var address []common.Address + var addresses []common.Address stmt := fmt.Sprintf(` SELECT allowed_address FROM %s @@ -145,26 +146,29 @@ func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common. OFFSET $2 LIMIT $3; `, allowlistTableName) - err := o.q.WithOpts(qopts...).Select(&address, stmt, o.routerContractAddress, offset, limit) + err := o.q.WithOpts(qopts...).Select(&addresses, stmt, o.routerContractAddress, offset, limit) if err != nil { - return address, err + return addresses, err } + o.lggr.Debugf("Successfully fetched allowed sender list from DB. offset: %d, limit: %d, length: %d", offset, limit, len(addresses)) - return address, nil + return addresses, nil } -func (o *orm) UpsertAllowedSender(id uint64, allowedSender common.Address, qopts ...pg.QOpt) error { +func (o *orm) CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOpt) error { stmt := fmt.Sprintf(` - INSERT INTO %s (id, allowed_address, router_contract_address) - VALUES ($1,$2,$3) ON CONFLICT (id, router_contract_address) DO UPDATE - SET allowed_address=$2, router_contract_address=$3;`, allowlistTableName) + INSERT INTO %s (allowed_address, router_contract_address) + VALUES ($1,$2) ON CONFLICT (allowed_address, router_contract_address) DO NOTHING;`, allowlistTableName) _, err := o.q.WithOpts(qopts...).Exec( stmt, - id, allowedSender, o.routerContractAddress, ) + if err != nil { + return err + } + o.lggr.Debugf("Successfully stored allowed sender: %s for routerContractAddress: %s", allowedSender, o.routerContractAddress) - return err + return nil } diff --git a/core/services/gateway/handlers/functions/orm_test.go b/core/services/gateway/handlers/functions/orm_test.go index 13411d95f0b..5e082855938 100644 --- a/core/services/gateway/handlers/functions/orm_test.go +++ b/core/services/gateway/handlers/functions/orm_test.go @@ -30,8 +30,8 @@ func setupORM(t *testing.T) (functions.ORM, error) { return functions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) } -func createSubscriptions(t *testing.T, orm functions.ORM, amount int) []functions.CachedSubscription { - cachedSubscriptions := make([]functions.CachedSubscription, 0) +func seedSubscriptions(t *testing.T, orm functions.ORM, amount int) []functions.CachedSubscription { + storedSubscriptions := make([]functions.CachedSubscription, 0) for i := amount; i > 0; i-- { cs := functions.CachedSubscription{ SubscriptionID: uint64(i), @@ -44,43 +44,45 @@ func createSubscriptions(t *testing.T, orm functions.ORM, amount int) []function Flags: defaultFlags, }, } - cachedSubscriptions = append(cachedSubscriptions, cs) + storedSubscriptions = append(storedSubscriptions, cs) err := orm.UpsertSubscription(cs) require.NoError(t, err) } - return cachedSubscriptions + return storedSubscriptions } -func createAllowedSenders(t *testing.T, orm functions.ORM, amount int) []common.Address { - cachedAllowedSenders := make([]common.Address, 0) - for i := amount; i > 0; i-- { +func seedAllowedSenders(t *testing.T, orm functions.ORM, amount int) []common.Address { + storedAllowedSenders := make([]common.Address, amount) + for i := 0; i < amount; i++ { address := testutils.NewAddress() - cachedAllowedSenders = append(cachedAllowedSenders, address) - err := orm.UpsertAllowedSender(uint64(i), address) + storedAllowedSenders[i] = address + err := orm.CreateAllowedSender(address) require.NoError(t, err) } - return cachedAllowedSenders + + return storedAllowedSenders } + func TestORM_GetSubscriptions(t *testing.T) { t.Parallel() t.Run("fetch first page", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - cachedSubscriptions := createSubscriptions(t, orm, 2) + storedSubscriptions := seedSubscriptions(t, orm, 2) results, err := orm.GetSubscriptions(0, 1) require.NoError(t, err) require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, cachedSubscriptions[1], results[0]) + require.Equal(t, storedSubscriptions[1], results[0]) }) t.Run("fetch second page", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - cachedSubscriptions := createSubscriptions(t, orm, 2) + storedSubscriptions := seedSubscriptions(t, orm, 2) results, err := orm.GetSubscriptions(1, 5) require.NoError(t, err) require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, cachedSubscriptions[0], results[0]) + require.Equal(t, storedSubscriptions[0], results[0]) }) } @@ -245,67 +247,54 @@ func TestORM_GetAllowedSenders(t *testing.T) { t.Run("fetch first page", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - cachedAllowedSenders := createAllowedSenders(t, orm, 2) + storedAllowedSenders := seedAllowedSenders(t, orm, 2) results, err := orm.GetAllowedSenders(0, 1) require.NoError(t, err) require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, cachedAllowedSenders[1], results[0]) + require.Equal(t, storedAllowedSenders[0], results[0]) }) t.Run("fetch second page", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - cachedAllowedSenders := createAllowedSenders(t, orm, 2) + storedAllowedSenders := seedAllowedSenders(t, orm, 2) results, err := orm.GetAllowedSenders(1, 5) require.NoError(t, err) require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, cachedAllowedSenders[0], results[0]) + require.Equal(t, storedAllowedSenders[1], results[0]) }) } -func TestORM_UpsertAllowedSender(t *testing.T) { +func TestORM_CreateAllowedSender(t *testing.T) { t.Parallel() - type allowedSender struct { - id uint64 - address common.Address - } - t.Run("create an allowed sender", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - expected := allowedSender{uint64(1), testutils.NewAddress()} - err = orm.UpsertAllowedSender(expected.id, expected.address) + expected := testutils.NewAddress() + err = orm.CreateAllowedSender(expected) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 1) require.NoError(t, err) require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, expected.address, results[0]) + require.Equal(t, expected, results[0]) }) - t.Run("update an allowed sender", func(t *testing.T) { + t.Run("create an existing allowed sender", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - - expectedUpdated := allowedSender{uint64(1), testutils.NewAddress()} - err = orm.UpsertAllowedSender(expectedUpdated.id, expectedUpdated.address) - require.NoError(t, err) - - expectedNotUpdated := allowedSender{uint64(2), testutils.NewAddress()} - err = orm.UpsertAllowedSender(expectedNotUpdated.id, expectedNotUpdated.address) + expected := testutils.NewAddress() + err = orm.CreateAllowedSender(expected) require.NoError(t, err) - // update the address - expectedUpdated.address = testutils.NewAddress() - err = orm.UpsertAllowedSender(expectedUpdated.id, expectedUpdated.address) + err = orm.CreateAllowedSender(expected) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 5) require.NoError(t, err) - require.Equal(t, 2, len(results), "incorrect results length") - require.Equal(t, expectedNotUpdated.address, results[1]) - require.Equal(t, expectedUpdated.address, results[0]) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, expected, results[0]) }) } diff --git a/core/store/migrate/migrations/0216_functions_allowlist.sql b/core/store/migrate/migrations/0220_functions_allowlist.sql similarity index 80% rename from core/store/migrate/migrations/0216_functions_allowlist.sql rename to core/store/migrate/migrations/0220_functions_allowlist.sql index 5eb40e101b8..6415344af18 100644 --- a/core/store/migrate/migrations/0216_functions_allowlist.sql +++ b/core/store/migrate/migrations/0220_functions_allowlist.sql @@ -1,10 +1,10 @@ -- +goose Up -- +goose StatementBegin CREATE TABLE functions_allowlist( - id bigint, + id BIGSERIAL, router_contract_address bytea, allowed_address bytea CHECK (octet_length(allowed_address) = 20) NOT NULL, - PRIMARY KEY(router_contract_address, id) + PRIMARY KEY(router_contract_address, allowed_address) ); -- +goose StatementEnd From 4b211095a7c5521a80c179c6774ab1585990ad8d Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Fri, 12 Jan 2024 18:44:10 +0100 Subject: [PATCH 10/23] feat: store allowlist in batches --- .../gateway/handlers/functions/allowlist.go | 22 +++++---- .../handlers/functions/allowlist_test.go | 43 ++--------------- .../gateway/handlers/functions/mocks/orm.go | 10 ++-- .../gateway/handlers/functions/orm.go | 23 +++++---- .../gateway/handlers/functions/orm_test.go | 47 ++++++++++++++++--- ...wlist.sql => 0221_functions_allowlist.sql} | 0 6 files changed, 77 insertions(+), 68 deletions(-) rename core/store/migrate/migrations/{0220_functions_allowlist.sql => 0221_functions_allowlist.sql} (100%) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 5aa55cb2488..4fa8700c95c 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -23,7 +23,7 @@ import ( ) const ( - defaultStoredAllowlistBatchSize = 100 + defaultStoredAllowlistBatchSize = 1000 defaultOnchainAllowlistBatchSize = 100 ) @@ -207,6 +207,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList := make([]common.Address, 0) + var storageWg sync.WaitGroup for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) if idxEnd >= count { @@ -223,10 +224,19 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList = append(allowedSenderList, allowedSendersBatch...) + + storageWg.Add(1) + go func(allowedSendersBatch []common.Address) { + defer storageWg.Done() + err = a.orm.CreateAllowedSender(allowedSendersBatch) + if err != nil { + a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) + } + }(allowedSendersBatch) } a.update(allowedSenderList) - a.updateStoredAllowedSenderList(allowedSenderList) + storageWg.Wait() return nil } @@ -239,14 +249,6 @@ func (a *onchainAllowlist) update(addrList []common.Address) { a.lggr.Infow("allowlist updated successfully", "len", len(addrList)) } -func (a *onchainAllowlist) updateStoredAllowedSenderList(addrList []common.Address) { - for _, addr := range addrList { - if err := a.orm.CreateAllowedSender(addr); err != nil { - a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) - } - } -} - func (a *onchainAllowlist) loadStoredAllowedSenderList() { allowedList := make([]common.Address, 0) offset := uint(0) diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index f96dc2b2bfb..20009c7fadb 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -50,8 +50,7 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Return(nil) + orm.On("CreateAllowedSender", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -102,9 +101,8 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("GetAllowedSenders", uint(0), uint(100)).Return([]common.Address{}, nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Return(nil) + orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) + orm.On("CreateAllowedSender", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -130,7 +128,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { cancel() }).Return(sampleEncodedAllowlist(t), nil) config := functions.OnchainAllowlistConfig{ - ContractAddress: common.Address{}, + ContractAddress: common.HexToAddress(addr3), ContractVersion: 1, BlockConfirmations: 1, UpdateFrequencySec: 1, @@ -140,38 +138,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr1)).Once().Return(nil) - orm.On("CreateAllowedSender", common.HexToAddress(addr2)).Once().Return(nil) + orm.On("CreateAllowedSender", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(16).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) diff --git a/core/services/gateway/handlers/functions/mocks/orm.go b/core/services/gateway/handlers/functions/mocks/orm.go index dbc9f18c403..433ebd7381b 100644 --- a/core/services/gateway/handlers/functions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/mocks/orm.go @@ -15,14 +15,14 @@ type ORM struct { mock.Mock } -// CreateAllowedSender provides a mock function with given fields: allowedSender, qopts -func (_m *ORM) CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOpt) error { +// CreateAllowedSender provides a mock function with given fields: allowedSenders, qopts +func (_m *ORM) CreateAllowedSender(allowedSenders []common.Address, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) for _i := range qopts { _va[_i] = qopts[_i] } var _ca []interface{} - _ca = append(_ca, allowedSender) + _ca = append(_ca, allowedSenders) _ca = append(_ca, _va...) ret := _m.Called(_ca...) @@ -31,8 +31,8 @@ func (_m *ORM) CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOp } var r0 error - if rf, ok := ret.Get(0).(func(common.Address, ...pg.QOpt) error); ok { - r0 = rf(allowedSender, qopts...) + if rf, ok := ret.Get(0).(func([]common.Address, ...pg.QOpt) error); ok { + r0 = rf(allowedSenders, qopts...) } else { r0 = ret.Error(0) } diff --git a/core/services/gateway/handlers/functions/orm.go b/core/services/gateway/handlers/functions/orm.go index c47b52d3b7f..db2a18bc398 100644 --- a/core/services/gateway/handlers/functions/orm.go +++ b/core/services/gateway/handlers/functions/orm.go @@ -3,6 +3,7 @@ package functions import ( "fmt" "math/big" + "strings" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" @@ -21,7 +22,7 @@ type ORM interface { UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) - CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOpt) error + CreateAllowedSender(allowedSenders []common.Address, qopts ...pg.QOpt) error } type orm struct { @@ -155,16 +156,22 @@ func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common. return addresses, nil } -func (o *orm) CreateAllowedSender(allowedSender common.Address, qopts ...pg.QOpt) error { +func (o *orm) CreateAllowedSender(allowedSender []common.Address, qopts ...pg.QOpt) error { + var valuesPlaceholder []string + for i := 1; i <= len(allowedSender)*2; i += 2 { + valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1)) + } + stmt := fmt.Sprintf(` INSERT INTO %s (allowed_address, router_contract_address) - VALUES ($1,$2) ON CONFLICT (allowed_address, router_contract_address) DO NOTHING;`, allowlistTableName) + VALUES %s ON CONFLICT (allowed_address, router_contract_address) DO NOTHING;`, allowlistTableName, strings.Join(valuesPlaceholder, ", ")) - _, err := o.q.WithOpts(qopts...).Exec( - stmt, - allowedSender, - o.routerContractAddress, - ) + var args []interface{} + for _, as := range allowedSender { + args = append(args, as, o.routerContractAddress) + } + + _, err := o.q.WithOpts(qopts...).Exec(stmt, args...) if err != nil { return err } diff --git a/core/services/gateway/handlers/functions/orm_test.go b/core/services/gateway/handlers/functions/orm_test.go index 5e082855938..109f1729dfd 100644 --- a/core/services/gateway/handlers/functions/orm_test.go +++ b/core/services/gateway/handlers/functions/orm_test.go @@ -56,10 +56,11 @@ func seedAllowedSenders(t *testing.T, orm functions.ORM, amount int) []common.Ad for i := 0; i < amount; i++ { address := testutils.NewAddress() storedAllowedSenders[i] = address - err := orm.CreateAllowedSender(address) - require.NoError(t, err) } + err := orm.CreateAllowedSender(storedAllowedSenders) + require.NoError(t, err) + return storedAllowedSenders } @@ -268,11 +269,11 @@ func TestORM_GetAllowedSenders(t *testing.T) { func TestORM_CreateAllowedSender(t *testing.T) { t.Parallel() - t.Run("create an allowed sender", func(t *testing.T) { + t.Run("OK-create_an_allowed_sender", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) expected := testutils.NewAddress() - err = orm.CreateAllowedSender(expected) + err = orm.CreateAllowedSender([]common.Address{expected}) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 1) @@ -281,14 +282,14 @@ func TestORM_CreateAllowedSender(t *testing.T) { require.Equal(t, expected, results[0]) }) - t.Run("create an existing allowed sender", func(t *testing.T) { + t.Run("OK-create_an_existing_allowed_sender", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) expected := testutils.NewAddress() - err = orm.CreateAllowedSender(expected) + err = orm.CreateAllowedSender([]common.Address{expected}) require.NoError(t, err) - err = orm.CreateAllowedSender(expected) + err = orm.CreateAllowedSender([]common.Address{expected}) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 5) @@ -296,6 +297,38 @@ func TestORM_CreateAllowedSender(t *testing.T) { require.Equal(t, 1, len(results), "incorrect results length") require.Equal(t, expected, results[0]) }) + + t.Run("OK-create_multiple_allowed_senders_in_one_query", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + expected := []common.Address{testutils.NewAddress(), testutils.NewAddress()} + err = orm.CreateAllowedSender(expected) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 2) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, expected[0], results[0]) + require.Equal(t, expected[1], results[1]) + }) + + t.Run("OK-create_multiple_allowed_senders_with_duplicates", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + addr1 := testutils.NewAddress() + addr2 := testutils.NewAddress() + expected := []common.Address{addr1, addr2} + + duplicatedAddressInput := []common.Address{addr1, addr1, addr1, addr2} + err = orm.CreateAllowedSender(duplicatedAddressInput) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, expected[0], results[0]) + require.Equal(t, expected[1], results[1]) + }) } func Test_NewORM(t *testing.T) { diff --git a/core/store/migrate/migrations/0220_functions_allowlist.sql b/core/store/migrate/migrations/0221_functions_allowlist.sql similarity index 100% rename from core/store/migrate/migrations/0220_functions_allowlist.sql rename to core/store/migrate/migrations/0221_functions_allowlist.sql From bf994cd120663931e0f53b0ae9a3042d5a24a66a Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Tue, 16 Jan 2024 12:32:02 +0100 Subject: [PATCH 11/23] chore: correct CreateAllowedSenders naming --- .../gateway/handlers/functions/allowlist.go | 2 +- .../gateway/handlers/functions/allowlist_test.go | 6 +++--- .../gateway/handlers/functions/mocks/orm.go | 6 +++--- core/services/gateway/handlers/functions/orm.go | 4 ++-- .../gateway/handlers/functions/orm_test.go | 14 +++++++------- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 4fa8700c95c..be1b08d192f 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -228,7 +228,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b storageWg.Add(1) go func(allowedSendersBatch []common.Address) { defer storageWg.Done() - err = a.orm.CreateAllowedSender(allowedSendersBatch) + err = a.orm.CreateAllowedSenders(allowedSendersBatch) if err != nil { a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) } diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index 20009c7fadb..d52425fcaed 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -50,7 +50,7 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("CreateAllowedSender", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -102,7 +102,7 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { orm := fmocks.NewORM(t) orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) - orm.On("CreateAllowedSender", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -138,7 +138,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { } orm := fmocks.NewORM(t) - orm.On("CreateAllowedSender", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(16).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(16).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) diff --git a/core/services/gateway/handlers/functions/mocks/orm.go b/core/services/gateway/handlers/functions/mocks/orm.go index 433ebd7381b..fed28a8e889 100644 --- a/core/services/gateway/handlers/functions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/mocks/orm.go @@ -15,8 +15,8 @@ type ORM struct { mock.Mock } -// CreateAllowedSender provides a mock function with given fields: allowedSenders, qopts -func (_m *ORM) CreateAllowedSender(allowedSenders []common.Address, qopts ...pg.QOpt) error { +// CreateAllowedSenders provides a mock function with given fields: allowedSenders, qopts +func (_m *ORM) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) for _i := range qopts { _va[_i] = qopts[_i] @@ -27,7 +27,7 @@ func (_m *ORM) CreateAllowedSender(allowedSenders []common.Address, qopts ...pg. ret := _m.Called(_ca...) if len(ret) == 0 { - panic("no return value specified for CreateAllowedSender") + panic("no return value specified for CreateAllowedSenders") } var r0 error diff --git a/core/services/gateway/handlers/functions/orm.go b/core/services/gateway/handlers/functions/orm.go index db2a18bc398..d0f6b0a7892 100644 --- a/core/services/gateway/handlers/functions/orm.go +++ b/core/services/gateway/handlers/functions/orm.go @@ -22,7 +22,7 @@ type ORM interface { UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) - CreateAllowedSender(allowedSenders []common.Address, qopts ...pg.QOpt) error + CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error } type orm struct { @@ -156,7 +156,7 @@ func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common. return addresses, nil } -func (o *orm) CreateAllowedSender(allowedSender []common.Address, qopts ...pg.QOpt) error { +func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.QOpt) error { var valuesPlaceholder []string for i := 1; i <= len(allowedSender)*2; i += 2 { valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1)) diff --git a/core/services/gateway/handlers/functions/orm_test.go b/core/services/gateway/handlers/functions/orm_test.go index 109f1729dfd..5d5b99e19ac 100644 --- a/core/services/gateway/handlers/functions/orm_test.go +++ b/core/services/gateway/handlers/functions/orm_test.go @@ -58,7 +58,7 @@ func seedAllowedSenders(t *testing.T, orm functions.ORM, amount int) []common.Ad storedAllowedSenders[i] = address } - err := orm.CreateAllowedSender(storedAllowedSenders) + err := orm.CreateAllowedSenders(storedAllowedSenders) require.NoError(t, err) return storedAllowedSenders @@ -266,14 +266,14 @@ func TestORM_GetAllowedSenders(t *testing.T) { }) } -func TestORM_CreateAllowedSender(t *testing.T) { +func TestORM_CreateAllowedSenders(t *testing.T) { t.Parallel() t.Run("OK-create_an_allowed_sender", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) expected := testutils.NewAddress() - err = orm.CreateAllowedSender([]common.Address{expected}) + err = orm.CreateAllowedSenders([]common.Address{expected}) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 1) @@ -286,10 +286,10 @@ func TestORM_CreateAllowedSender(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) expected := testutils.NewAddress() - err = orm.CreateAllowedSender([]common.Address{expected}) + err = orm.CreateAllowedSenders([]common.Address{expected}) require.NoError(t, err) - err = orm.CreateAllowedSender([]common.Address{expected}) + err = orm.CreateAllowedSenders([]common.Address{expected}) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 5) @@ -302,7 +302,7 @@ func TestORM_CreateAllowedSender(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) expected := []common.Address{testutils.NewAddress(), testutils.NewAddress()} - err = orm.CreateAllowedSender(expected) + err = orm.CreateAllowedSenders(expected) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 2) @@ -320,7 +320,7 @@ func TestORM_CreateAllowedSender(t *testing.T) { expected := []common.Address{addr1, addr2} duplicatedAddressInput := []common.Address{addr1, addr1, addr1, addr2} - err = orm.CreateAllowedSender(duplicatedAddressInput) + err = orm.CreateAllowedSenders(duplicatedAddressInput) require.NoError(t, err) results, err := orm.GetAllowedSenders(0, 10) From 3ede89909a74d4d26f01a69ed00774e8609f70d2 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Tue, 16 Jan 2024 12:59:13 +0100 Subject: [PATCH 12/23] chore: CreateAllowedSenders in main routine --- .../gateway/handlers/functions/allowlist.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index be1b08d192f..eb9903fecb1 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -207,7 +207,6 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList := make([]common.Address, 0) - var storageWg sync.WaitGroup for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) if idxEnd >= count { @@ -225,18 +224,13 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b allowedSenderList = append(allowedSenderList, allowedSendersBatch...) - storageWg.Add(1) - go func(allowedSendersBatch []common.Address) { - defer storageWg.Done() - err = a.orm.CreateAllowedSenders(allowedSendersBatch) - if err != nil { - a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) - } - }(allowedSendersBatch) + err = a.orm.CreateAllowedSenders(allowedSendersBatch) + if err != nil { + a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) + } } a.update(allowedSenderList) - storageWg.Wait() return nil } From b07c45416c20448576e58268e96f0a6b56e8a2aa Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Tue, 16 Jan 2024 15:26:37 +0100 Subject: [PATCH 13/23] fix: add a trottle to prevent RPC rate limiting --- .../gateway/handlers/functions/allowlist.go | 24 +++++++++++++------ .../handlers/functions/allowlist_test.go | 5 ++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index eb9903fecb1..5d99ab1681d 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -25,6 +25,7 @@ import ( const ( defaultStoredAllowlistBatchSize = 1000 defaultOnchainAllowlistBatchSize = 100 + defaultFetchingDelayInRangeSec = 1 ) type OnchainAllowlistConfig struct { @@ -33,8 +34,10 @@ type OnchainAllowlistConfig struct { ContractVersion uint32 `json:"contractVersion"` BlockConfirmations uint `json:"blockConfirmations"` // UpdateFrequencySec can be zero to disable periodic updates - UpdateFrequencySec uint `json:"updateFrequencySec"` - UpdateTimeoutSec uint `json:"updateTimeoutSec"` + UpdateFrequencySec uint `json:"updateFrequencySec"` + UpdateTimeoutSec uint `json:"updateTimeoutSec"` + // FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist. + FetchingDelayInRangeSec uint `json:"fetchingDelayInRangeSec"` StoredAllowlistBatchSize uint `json:"storedAllowlistBatchSize"` OnchainAllowlistBatchSize uint `json:"onchainAllowlistBatchSize"` } @@ -77,18 +80,21 @@ func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, return nil, fmt.Errorf("unsupported contract version %d", config.ContractVersion) } - // if StoredAllowlistBatchSize is not specified used the default value if config.StoredAllowlistBatchSize == 0 { lggr.Info("StoredAllowlistBatchSize not specified, using default size: ", defaultStoredAllowlistBatchSize) config.StoredAllowlistBatchSize = defaultStoredAllowlistBatchSize } - // if OnchainAllowlistBatchSize is not specified used the default value if config.OnchainAllowlistBatchSize == 0 { lggr.Info("OnchainAllowlistBatchSize not specified, using default size: ", defaultOnchainAllowlistBatchSize) config.OnchainAllowlistBatchSize = defaultOnchainAllowlistBatchSize } + if config.FetchingDelayInRangeSec == 0 { + lggr.Info("FetchingDelayInRangeSec not specified, using default size: ", defaultOnchainAllowlistBatchSize) + config.FetchingDelayInRangeSec = defaultFetchingDelayInRangeSec + } + contractV1, err := functions_router.NewFunctionsRouter(config.ContractAddress, client) if err != nil { return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err) @@ -115,6 +121,8 @@ func (a *onchainAllowlist) Start(ctx context.Context) error { return nil } + a.loadStoredAllowedSenderList() + updateOnce := func() { timeoutCtx, cancel := utils.ContextFromChanWithTimeout(a.stopCh, time.Duration(a.config.UpdateTimeoutSec)*time.Second) if err := a.UpdateFromContract(timeoutCtx); err != nil { @@ -123,8 +131,6 @@ func (a *onchainAllowlist) Start(ctx context.Context) error { cancel() } - a.loadStoredAllowedSenderList() - a.closeWait.Add(1) go func() { defer a.closeWait.Done() @@ -207,7 +213,11 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList := make([]common.Address, 0) + + throttleTicker := time.NewTicker(time.Duration(a.config.FetchingDelayInRangeSec) * time.Second) for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { + <-throttleTicker.C + idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) if idxEnd >= count { idxEnd = count - 1 @@ -223,12 +233,12 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList = append(allowedSenderList, allowedSendersBatch...) - err = a.orm.CreateAllowedSenders(allowedSendersBatch) if err != nil { a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) } } + throttleTicker.Stop() a.update(allowedSenderList) return nil diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist_test.go index d52425fcaed..995f10c0ca1 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist_test.go @@ -134,11 +134,12 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { UpdateFrequencySec: 1, UpdateTimeoutSec: 1, StoredAllowlistBatchSize: 2, - OnchainAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 32, + FetchingDelayInRangeSec: 0, } orm := fmocks.NewORM(t) - orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(16).Return(nil) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) From f410edfb39d437048f0682b93370d7040e661225 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Wed, 17 Jan 2024 14:09:44 +0100 Subject: [PATCH 14/23] chore: split orm in subscriptions and allowlist pkgs --- core/services/functions/connector_handler.go | 8 +- .../functions/connector_handler_test.go | 7 +- .../functions/{ => allowlist}/allowlist.go | 2 +- .../{ => allowlist}/allowlist_test.go | 30 ++-- .../mocks/onchain_allowlist.go | 0 .../functions/{ => allowlist}/mocks/orm.go | 63 -------- .../handlers/functions/allowlist/orm.go | 90 ++++++++++++ .../handlers/functions/allowlist/orm_test.go | 139 ++++++++++++++++++ .../handlers/functions/handler.functions.go | 28 ++-- .../functions/handler.functions_test.go | 9 +- .../mocks/onchain_subscriptions.go | 0 .../functions/subscriptions/mocks/orm.go | 90 ++++++++++++ .../functions/{ => subscriptions}/orm.go | 56 +------ .../functions/{ => subscriptions}/orm_test.go | 136 +++-------------- .../{ => subscriptions}/subscriptions.go | 2 +- .../{ => subscriptions}/subscriptions_test.go | 32 ++-- .../{ => subscriptions}/user_subscriptions.go | 2 +- .../user_subscriptions_test.go | 16 +- .../ocr2/plugins/functions/config/config.go | 59 ++++---- .../services/ocr2/plugins/functions/plugin.go | 17 ++- .../ocr2/plugins/functions/plugin_test.go | 11 +- 21 files changed, 458 insertions(+), 339 deletions(-) rename core/services/gateway/handlers/functions/{ => allowlist}/allowlist.go (99%) rename core/services/gateway/handlers/functions/{ => allowlist}/allowlist_test.go (86%) rename core/services/gateway/handlers/functions/{ => allowlist}/mocks/onchain_allowlist.go (100%) rename core/services/gateway/handlers/functions/{ => allowlist}/mocks/orm.go (56%) create mode 100644 core/services/gateway/handlers/functions/allowlist/orm.go create mode 100644 core/services/gateway/handlers/functions/allowlist/orm_test.go rename core/services/gateway/handlers/functions/{ => subscriptions}/mocks/onchain_subscriptions.go (100%) create mode 100644 core/services/gateway/handlers/functions/subscriptions/mocks/orm.go rename core/services/gateway/handlers/functions/{ => subscriptions}/orm.go (68%) rename core/services/gateway/handlers/functions/{ => subscriptions}/orm_test.go (61%) rename core/services/gateway/handlers/functions/{ => subscriptions}/subscriptions.go (99%) rename core/services/gateway/handlers/functions/{ => subscriptions}/subscriptions_test.go (91%) rename core/services/gateway/handlers/functions/{ => subscriptions}/user_subscriptions.go (99%) rename core/services/gateway/handlers/functions/{ => subscriptions}/user_subscriptions_test.go (92%) diff --git a/core/services/functions/connector_handler.go b/core/services/functions/connector_handler.go index 18df644c876..c8c522e6a62 100644 --- a/core/services/functions/connector_handler.go +++ b/core/services/functions/connector_handler.go @@ -26,6 +26,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + fallow "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" + fsub "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" "github.com/smartcontractkit/chainlink/v2/core/services/s4" ) @@ -37,9 +39,9 @@ type functionsConnectorHandler struct { signerKey *ecdsa.PrivateKey nodeAddress string storage s4.Storage - allowlist functions.OnchainAllowlist + allowlist fallow.OnchainAllowlist rateLimiter *hc.RateLimiter - subscriptions functions.OnchainSubscriptions + subscriptions fsub.OnchainSubscriptions minimumBalance assets.Link listener FunctionsListener offchainTransmitter OffchainTransmitter @@ -72,7 +74,7 @@ func InternalId(sender []byte, requestId []byte) RequestID { return RequestID(crypto.Keccak256Hash(append(sender, requestId...)).Bytes()) } -func NewFunctionsConnectorHandler(pluginConfig *config.PluginConfig, signerKey *ecdsa.PrivateKey, storage s4.Storage, allowlist functions.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions functions.OnchainSubscriptions, listener FunctionsListener, offchainTransmitter OffchainTransmitter, lggr logger.Logger) (*functionsConnectorHandler, error) { +func NewFunctionsConnectorHandler(pluginConfig *config.PluginConfig, signerKey *ecdsa.PrivateKey, storage s4.Storage, allowlist fallow.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions fsub.OnchainSubscriptions, listener FunctionsListener, offchainTransmitter OffchainTransmitter, lggr logger.Logger) (*functionsConnectorHandler, error) { if signerKey == nil || storage == nil || allowlist == nil || rateLimiter == nil || subscriptions == nil || listener == nil || offchainTransmitter == nil { return nil, fmt.Errorf("all dependencies must be non-nil") } diff --git a/core/services/functions/connector_handler_test.go b/core/services/functions/connector_handler_test.go index 9a5a9042693..aadc84ba96a 100644 --- a/core/services/functions/connector_handler_test.go +++ b/core/services/functions/connector_handler_test.go @@ -23,7 +23,8 @@ import ( gwconnector "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" gcmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector/mocks" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" - gfmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/mocks" + fallowMocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist/mocks" + fsubMocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" "github.com/smartcontractkit/chainlink/v2/core/services/s4" s4mocks "github.com/smartcontractkit/chainlink/v2/core/services/s4/mocks" @@ -66,9 +67,9 @@ func TestFunctionsConnectorHandler(t *testing.T) { privateKey, addr := testutils.NewPrivateKeyAndAddress(t) storage := s4mocks.NewStorage(t) connector := gcmocks.NewGatewayConnector(t) - allowlist := gfmocks.NewOnchainAllowlist(t) + allowlist := fallowMocks.NewOnchainAllowlist(t) rateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100}) - subscriptions := gfmocks.NewOnchainSubscriptions(t) + subscriptions := fsubMocks.NewOnchainSubscriptions(t) reportCh := make(chan *functions.OffchainResponse) offchainTransmitter := sfmocks.NewOffchainTransmitter(t) offchainTransmitter.On("ReportChannel", mock.Anything).Return(reportCh) diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go similarity index 99% rename from core/services/gateway/handlers/functions/allowlist.go rename to core/services/gateway/handlers/functions/allowlist/allowlist.go index 5d99ab1681d..5bfe78a968b 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -1,4 +1,4 @@ -package functions +package allowlist import ( "context" diff --git a/core/services/gateway/handlers/functions/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go similarity index 86% rename from core/services/gateway/handlers/functions/allowlist_test.go rename to core/services/gateway/handlers/functions/allowlist/allowlist_test.go index 995f10c0ca1..a1d474d97e1 100644 --- a/core/services/gateway/handlers/functions/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -1,4 +1,4 @@ -package functions_test +package allowlist_test import ( "context" @@ -16,8 +16,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client/mocks" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" - fmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" + amocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist/mocks" ) const ( @@ -43,16 +43,16 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { client := mocks.NewClient(t) client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(sampleEncodedAllowlist(t), nil) - config := functions.OnchainAllowlistConfig{ + config := allowlist.OnchainAllowlistConfig{ ContractVersion: 1, ContractAddress: common.Address{}, BlockConfirmations: 1, } - orm := fmocks.NewORM(t) + orm := amocks.NewORM(t) orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) - allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = allowlist.Start(testutils.Context(t)) @@ -72,14 +72,14 @@ func TestAllowlist_UnsupportedVersion(t *testing.T) { t.Parallel() client := mocks.NewClient(t) - config := functions.OnchainAllowlistConfig{ + config := allowlist.OnchainAllowlistConfig{ ContractVersion: 0, ContractAddress: common.Address{}, BlockConfirmations: 1, } - orm := fmocks.NewORM(t) - _, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + orm := amocks.NewORM(t) + _, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.Error(t, err) } @@ -92,7 +92,7 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { cancel() }).Return(sampleEncodedAllowlist(t), nil) - config := functions.OnchainAllowlistConfig{ + config := allowlist.OnchainAllowlistConfig{ ContractAddress: common.Address{}, ContractVersion: 1, BlockConfirmations: 1, @@ -100,11 +100,11 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { UpdateTimeoutSec: 1, } - orm := fmocks.NewORM(t) + orm := amocks.NewORM(t) orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) - allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = allowlist.Start(ctx) @@ -127,7 +127,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { cancel() }).Return(sampleEncodedAllowlist(t), nil) - config := functions.OnchainAllowlistConfig{ + config := allowlist.OnchainAllowlistConfig{ ContractAddress: common.HexToAddress(addr3), ContractVersion: 1, BlockConfirmations: 1, @@ -138,10 +138,10 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { FetchingDelayInRangeSec: 0, } - orm := fmocks.NewORM(t) + orm := amocks.NewORM(t) orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) - allowlist, err := functions.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = allowlist.UpdateFromContract(ctx) diff --git a/core/services/gateway/handlers/functions/mocks/onchain_allowlist.go b/core/services/gateway/handlers/functions/allowlist/mocks/onchain_allowlist.go similarity index 100% rename from core/services/gateway/handlers/functions/mocks/onchain_allowlist.go rename to core/services/gateway/handlers/functions/allowlist/mocks/onchain_allowlist.go diff --git a/core/services/gateway/handlers/functions/mocks/orm.go b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go similarity index 56% rename from core/services/gateway/handlers/functions/mocks/orm.go rename to core/services/gateway/handlers/functions/allowlist/mocks/orm.go index fed28a8e889..b9ef20e3fdf 100644 --- a/core/services/gateway/handlers/functions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go @@ -4,7 +4,6 @@ package mocks import ( common "github.com/ethereum/go-ethereum/common" - functions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" mock "github.com/stretchr/testify/mock" pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" @@ -77,68 +76,6 @@ func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]c return r0, r1 } -// GetSubscriptions provides a mock function with given fields: offset, limit, qopts -func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]functions.CachedSubscription, error) { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, offset, limit) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for GetSubscriptions") - } - - var r0 []functions.CachedSubscription - var r1 error - if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]functions.CachedSubscription, error)); ok { - return rf(offset, limit, qopts...) - } - if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []functions.CachedSubscription); ok { - r0 = rf(offset, limit, qopts...) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]functions.CachedSubscription) - } - } - - if rf, ok := ret.Get(1).(func(uint, uint, ...pg.QOpt) error); ok { - r1 = rf(offset, limit, qopts...) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpsertSubscription provides a mock function with given fields: subscription, qopts -func (_m *ORM) UpsertSubscription(subscription functions.CachedSubscription, qopts ...pg.QOpt) error { - _va := make([]interface{}, len(qopts)) - for _i := range qopts { - _va[_i] = qopts[_i] - } - var _ca []interface{} - _ca = append(_ca, subscription) - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) - - if len(ret) == 0 { - panic("no return value specified for UpsertSubscription") - } - - var r0 error - if rf, ok := ret.Get(0).(func(functions.CachedSubscription, ...pg.QOpt) error); ok { - r0 = rf(subscription, qopts...) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // NewORM creates a new instance of ORM. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewORM(t interface { diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go new file mode 100644 index 00000000000..90cc1fa8c30 --- /dev/null +++ b/core/services/gateway/handlers/functions/allowlist/orm.go @@ -0,0 +1,90 @@ +package allowlist + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + "github.com/jmoiron/sqlx" + + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +//go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore +type ORM interface { + GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) + CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error +} + +type orm struct { + q pg.Q + lggr logger.Logger + routerContractAddress common.Address +} + +var _ ORM = (*orm)(nil) +var ( + ErrInvalidParameters = errors.New("invalid parameters provided to create a functions contract cache ORM") +) + +const ( + tableName = "functions_allowlist" +) + +func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, routerContractAddress common.Address) (ORM, error) { + if db == nil || cfg == nil || lggr == nil || routerContractAddress == (common.Address{}) { + return nil, ErrInvalidParameters + } + + return &orm{ + q: pg.NewQ(db, lggr, cfg), + lggr: lggr, + routerContractAddress: routerContractAddress, + }, nil +} + +func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { + var addresses []common.Address + stmt := fmt.Sprintf(` + SELECT allowed_address + FROM %s + WHERE router_contract_address = $1 + ORDER BY id ASC + OFFSET $2 + LIMIT $3; + `, tableName) + err := o.q.WithOpts(qopts...).Select(&addresses, stmt, o.routerContractAddress, offset, limit) + if err != nil { + return addresses, err + } + o.lggr.Debugf("Successfully fetched allowed sender list from DB. offset: %d, limit: %d, length: %d", offset, limit, len(addresses)) + + return addresses, nil +} + +func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.QOpt) error { + var valuesPlaceholder []string + for i := 1; i <= len(allowedSender)*2; i += 2 { + valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1)) + } + + stmt := fmt.Sprintf(` + INSERT INTO %s (allowed_address, router_contract_address) + VALUES %s ON CONFLICT (allowed_address, router_contract_address) DO NOTHING;`, tableName, strings.Join(valuesPlaceholder, ", ")) + + var args []interface{} + for _, as := range allowedSender { + args = append(args, as, o.routerContractAddress) + } + + _, err := o.q.WithOpts(qopts...).Exec(stmt, args...) + if err != nil { + return err + } + o.lggr.Debugf("Successfully stored allowed sender: %s for routerContractAddress: %s", allowedSender, o.routerContractAddress) + + return nil +} diff --git a/core/services/gateway/handlers/functions/allowlist/orm_test.go b/core/services/gateway/handlers/functions/allowlist/orm_test.go new file mode 100644 index 00000000000..8b96afc6745 --- /dev/null +++ b/core/services/gateway/handlers/functions/allowlist/orm_test.go @@ -0,0 +1,139 @@ +package allowlist_test + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" +) + +func setupORM(t *testing.T) (allowlist.ORM, error) { + t.Helper() + + var ( + db = pgtest.NewSqlxDB(t) + lggr = logger.TestLogger(t) + ) + + return allowlist.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) +} + +func seedAllowedSenders(t *testing.T, orm allowlist.ORM, amount int) []common.Address { + storedAllowedSenders := make([]common.Address, amount) + for i := 0; i < amount; i++ { + address := testutils.NewAddress() + storedAllowedSenders[i] = address + } + + err := orm.CreateAllowedSenders(storedAllowedSenders) + require.NoError(t, err) + + return storedAllowedSenders +} +func TestORM_GetAllowedSenders(t *testing.T) { + t.Parallel() + t.Run("fetch first page", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + storedAllowedSenders := seedAllowedSenders(t, orm, 2) + results, err := orm.GetAllowedSenders(0, 1) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, storedAllowedSenders[0], results[0]) + }) + + t.Run("fetch second page", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + storedAllowedSenders := seedAllowedSenders(t, orm, 2) + results, err := orm.GetAllowedSenders(1, 5) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, storedAllowedSenders[1], results[0]) + }) +} + +func TestORM_CreateAllowedSenders(t *testing.T) { + t.Parallel() + + t.Run("OK-create_an_allowed_sender", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + expected := testutils.NewAddress() + err = orm.CreateAllowedSenders([]common.Address{expected}) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 1) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, expected, results[0]) + }) + + t.Run("OK-create_an_existing_allowed_sender", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + expected := testutils.NewAddress() + err = orm.CreateAllowedSenders([]common.Address{expected}) + require.NoError(t, err) + + err = orm.CreateAllowedSenders([]common.Address{expected}) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 5) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, expected, results[0]) + }) + + t.Run("OK-create_multiple_allowed_senders_in_one_query", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + expected := []common.Address{testutils.NewAddress(), testutils.NewAddress()} + err = orm.CreateAllowedSenders(expected) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 2) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, expected[0], results[0]) + require.Equal(t, expected[1], results[1]) + }) + + t.Run("OK-create_multiple_allowed_senders_with_duplicates", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + addr1 := testutils.NewAddress() + addr2 := testutils.NewAddress() + expected := []common.Address{addr1, addr2} + + duplicatedAddressInput := []common.Address{addr1, addr1, addr1, addr2} + err = orm.CreateAllowedSenders(duplicatedAddressInput) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, expected[0], results[0]) + require.Equal(t, expected[1], results[1]) + }) +} + +func Test_NewORM(t *testing.T) { + t.Run("OK-create_ORM", func(t *testing.T) { + _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress()) + require.NoError(t, err) + }) + t.Run("NOK-create_ORM_with_nil_fields", func(t *testing.T) { + _, err := allowlist.NewORM(nil, nil, nil, common.Address{}) + require.Error(t, err) + }) + t.Run("NOK-create_ORM_with_empty_address", func(t *testing.T) { + _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), common.Address{}) + require.Error(t, err) + }) +} diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go index 06ad2f50e47..118ed4b7dec 100644 --- a/core/services/gateway/handlers/functions/handler.functions.go +++ b/core/services/gateway/handlers/functions/handler.functions.go @@ -23,6 +23,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/config" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" + all "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" + sub "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -60,10 +62,10 @@ var ( type FunctionsHandlerConfig struct { ChainID string `json:"chainId"` // Not specifying OnchainAllowlist config disables allowlist checks - OnchainAllowlist *OnchainAllowlistConfig `json:"onchainAllowlist"` + OnchainAllowlist *all.OnchainAllowlistConfig `json:"onchainAllowlist"` // Not specifying OnchainSubscriptions config disables minimum balance checks - OnchainSubscriptions *OnchainSubscriptionsConfig `json:"onchainSubscriptions"` - MinimumSubscriptionBalance *assets.Link `json:"minimumSubscriptionBalance"` + OnchainSubscriptions *sub.OnchainSubscriptionsConfig `json:"onchainSubscriptions"` + MinimumSubscriptionBalance *assets.Link `json:"minimumSubscriptionBalance"` // Not specifying RateLimiter config disables rate limiting UserRateLimiter *hc.RateLimiterConfig `json:"userRateLimiter"` NodeRateLimiter *hc.RateLimiterConfig `json:"nodeRateLimiter"` @@ -79,8 +81,8 @@ type functionsHandler struct { donConfig *config.DONConfig don handlers.DON pendingRequests hc.RequestCache[PendingRequest] - allowlist OnchainAllowlist - subscriptions OnchainSubscriptions + allowlist all.OnchainAllowlist + subscriptions sub.OnchainSubscriptions minimumBalance *assets.Link userRateLimiter *hc.RateLimiter nodeRateLimiter *hc.RateLimiter @@ -105,18 +107,18 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con return nil, err } lggr = lggr.Named("FunctionsHandler:" + donConfig.DonId) - var allowlist OnchainAllowlist + var allowlist all.OnchainAllowlist if cfg.OnchainAllowlist != nil { chain, err2 := legacyChains.Get(cfg.ChainID) if err2 != nil { return nil, err2 } - orm, err2 := NewORM(db, lggr, qcfg, cfg.OnchainAllowlist.ContractAddress) + orm, err2 := all.NewORM(db, lggr, qcfg, cfg.OnchainAllowlist.ContractAddress) if err2 != nil { return nil, err2 } - allowlist, err2 = NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, orm, lggr) + allowlist, err2 = all.NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, orm, lggr) if err2 != nil { return nil, err2 } @@ -134,19 +136,19 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con return nil, err } } - var subscriptions OnchainSubscriptions + var subscriptions sub.OnchainSubscriptions if cfg.OnchainSubscriptions != nil { chain, err2 := legacyChains.Get(cfg.ChainID) if err2 != nil { return nil, err2 } - orm, err2 := NewORM(db, lggr, qcfg, cfg.OnchainSubscriptions.ContractAddress) + orm, err2 := sub.NewORM(db, lggr, qcfg, cfg.OnchainSubscriptions.ContractAddress) if err2 != nil { return nil, err2 } - subscriptions, err2 = NewOnchainSubscriptions(chain.Client(), *cfg.OnchainSubscriptions, orm, lggr) + subscriptions, err2 = sub.NewOnchainSubscriptions(chain.Client(), *cfg.OnchainSubscriptions, orm, lggr) if err2 != nil { return nil, err2 } @@ -164,8 +166,8 @@ func NewFunctionsHandler( donConfig *config.DONConfig, don handlers.DON, pendingRequestsCache hc.RequestCache[PendingRequest], - allowlist OnchainAllowlist, - subscriptions OnchainSubscriptions, + allowlist all.OnchainAllowlist, + subscriptions sub.OnchainSubscriptions, minimumBalance *assets.Link, userRateLimiter *hc.RateLimiter, nodeRateLimiter *hc.RateLimiter, diff --git a/core/services/gateway/handlers/functions/handler.functions_test.go b/core/services/gateway/handlers/functions/handler.functions_test.go index 7e055815c88..2e2c1c77caf 100644 --- a/core/services/gateway/handlers/functions/handler.functions_test.go +++ b/core/services/gateway/handlers/functions/handler.functions_test.go @@ -22,11 +22,12 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" - functions_mocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/mocks" + allowlist_mocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist/mocks" + subscriptions_mocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions/mocks" handlers_mocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/mocks" ) -func newFunctionsHandlerForATestDON(t *testing.T, nodes []gc.TestNode, requestTimeout time.Duration, heartbeatSender string) (handlers.Handler, *handlers_mocks.DON, *functions_mocks.OnchainAllowlist, *functions_mocks.OnchainSubscriptions) { +func newFunctionsHandlerForATestDON(t *testing.T, nodes []gc.TestNode, requestTimeout time.Duration, heartbeatSender string) (handlers.Handler, *handlers_mocks.DON, *allowlist_mocks.OnchainAllowlist, *subscriptions_mocks.OnchainSubscriptions) { cfg := functions.FunctionsHandlerConfig{} donConfig := &config.DONConfig{ Members: []config.NodeConfig{}, @@ -41,8 +42,8 @@ func newFunctionsHandlerForATestDON(t *testing.T, nodes []gc.TestNode, requestTi } don := handlers_mocks.NewDON(t) - allowlist := functions_mocks.NewOnchainAllowlist(t) - subscriptions := functions_mocks.NewOnchainSubscriptions(t) + allowlist := allowlist_mocks.NewOnchainAllowlist(t) + subscriptions := subscriptions_mocks.NewOnchainSubscriptions(t) minBalance := assets.NewLinkFromJuels(100) userRateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100}) require.NoError(t, err) diff --git a/core/services/gateway/handlers/functions/mocks/onchain_subscriptions.go b/core/services/gateway/handlers/functions/subscriptions/mocks/onchain_subscriptions.go similarity index 100% rename from core/services/gateway/handlers/functions/mocks/onchain_subscriptions.go rename to core/services/gateway/handlers/functions/subscriptions/mocks/onchain_subscriptions.go diff --git a/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go b/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go new file mode 100644 index 00000000000..a4406c4fda1 --- /dev/null +++ b/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go @@ -0,0 +1,90 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +package mocks + +import ( + subscriptions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" + mock "github.com/stretchr/testify/mock" +) + +// ORM is an autogenerated mock type for the ORM type +type ORM struct { + mock.Mock +} + +// GetSubscriptions provides a mock function with given fields: offset, limit, qopts +func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]subscriptions.CachedSubscription, error) { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, offset, limit) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for GetSubscriptions") + } + + var r0 []subscriptions.CachedSubscription + var r1 error + if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]subscriptions.CachedSubscription, error)); ok { + return rf(offset, limit, qopts...) + } + if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []subscriptions.CachedSubscription); ok { + r0 = rf(offset, limit, qopts...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]subscriptions.CachedSubscription) + } + } + + if rf, ok := ret.Get(1).(func(uint, uint, ...pg.QOpt) error); ok { + r1 = rf(offset, limit, qopts...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpsertSubscription provides a mock function with given fields: subscription, qopts +func (_m *ORM) UpsertSubscription(subscription subscriptions.CachedSubscription, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, subscription) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for UpsertSubscription") + } + + var r0 error + if rf, ok := ret.Get(0).(func(subscriptions.CachedSubscription, ...pg.QOpt) error); ok { + r0 = rf(subscription, qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewORM creates a new instance of ORM. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewORM(t interface { + mock.TestingT + Cleanup(func()) +}) *ORM { + mock := &ORM{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/gateway/handlers/functions/orm.go b/core/services/gateway/handlers/functions/subscriptions/orm.go similarity index 68% rename from core/services/gateway/handlers/functions/orm.go rename to core/services/gateway/handlers/functions/subscriptions/orm.go index d0f6b0a7892..297713325a0 100644 --- a/core/services/gateway/handlers/functions/orm.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm.go @@ -1,9 +1,8 @@ -package functions +package subscriptions import ( "fmt" "math/big" - "strings" "github.com/ethereum/go-ethereum/common" "github.com/lib/pq" @@ -20,9 +19,6 @@ import ( type ORM interface { GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSubscription, error) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error - - GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) - CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error } type orm struct { @@ -37,8 +33,7 @@ var ( ) const ( - subscriptionsTableName = "functions_subscriptions" - allowlistTableName = "functions_allowlist" + tableName = "functions_subscriptions" ) type cachedSubscriptionRow struct { @@ -74,7 +69,7 @@ func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSu ORDER BY subscription_id ASC OFFSET $2 LIMIT $3; - `, subscriptionsTableName) + `, tableName) err := o.q.WithOpts(qopts...).Select(&cacheSubscriptionRows, stmt, o.routerContractAddress, offset, limit) if err != nil { return cacheSubscriptions, err @@ -93,7 +88,7 @@ func (o *orm) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QO stmt := fmt.Sprintf(` INSERT INTO %s (subscription_id, owner, balance, blocked_balance, proposed_owner, consumers, flags, router_contract_address) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT (subscription_id, router_contract_address) DO UPDATE - SET owner=$2, balance=$3, blocked_balance=$4, proposed_owner=$5, consumers=$6, flags=$7, router_contract_address=$8;`, subscriptionsTableName) + SET owner=$2, balance=$3, blocked_balance=$4, proposed_owner=$5, consumers=$6, flags=$7, router_contract_address=$8;`, tableName) if subscription.Balance == nil { subscription.Balance = big.NewInt(0) @@ -136,46 +131,3 @@ func (cs *cachedSubscriptionRow) encode() CachedSubscription { }, } } - -func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { - var addresses []common.Address - stmt := fmt.Sprintf(` - SELECT allowed_address - FROM %s - WHERE router_contract_address = $1 - ORDER BY id ASC - OFFSET $2 - LIMIT $3; - `, allowlistTableName) - err := o.q.WithOpts(qopts...).Select(&addresses, stmt, o.routerContractAddress, offset, limit) - if err != nil { - return addresses, err - } - o.lggr.Debugf("Successfully fetched allowed sender list from DB. offset: %d, limit: %d, length: %d", offset, limit, len(addresses)) - - return addresses, nil -} - -func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.QOpt) error { - var valuesPlaceholder []string - for i := 1; i <= len(allowedSender)*2; i += 2 { - valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1)) - } - - stmt := fmt.Sprintf(` - INSERT INTO %s (allowed_address, router_contract_address) - VALUES %s ON CONFLICT (allowed_address, router_contract_address) DO NOTHING;`, allowlistTableName, strings.Join(valuesPlaceholder, ", ")) - - var args []interface{} - for _, as := range allowedSender { - args = append(args, as, o.routerContractAddress) - } - - _, err := o.q.WithOpts(qopts...).Exec(stmt, args...) - if err != nil { - return err - } - o.lggr.Debugf("Successfully stored allowed sender: %s for routerContractAddress: %s", allowedSender, o.routerContractAddress) - - return nil -} diff --git a/core/services/gateway/handlers/functions/orm_test.go b/core/services/gateway/handlers/functions/subscriptions/orm_test.go similarity index 61% rename from core/services/gateway/handlers/functions/orm_test.go rename to core/services/gateway/handlers/functions/subscriptions/orm_test.go index 5d5b99e19ac..f7720fe678c 100644 --- a/core/services/gateway/handlers/functions/orm_test.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm_test.go @@ -1,4 +1,4 @@ -package functions_test +package subscriptions_test import ( "math/big" @@ -12,14 +12,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" ) var ( defaultFlags = [32]byte{0x1, 0x2, 0x3} ) -func setupORM(t *testing.T) (functions.ORM, error) { +func setupORM(t *testing.T) (subscriptions.ORM, error) { t.Helper() var ( @@ -27,13 +27,13 @@ func setupORM(t *testing.T) (functions.ORM, error) { lggr = logger.TestLogger(t) ) - return functions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) + return subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) } -func seedSubscriptions(t *testing.T, orm functions.ORM, amount int) []functions.CachedSubscription { - storedSubscriptions := make([]functions.CachedSubscription, 0) +func seedSubscriptions(t *testing.T, orm subscriptions.ORM, amount int) []subscriptions.CachedSubscription { + storedSubscriptions := make([]subscriptions.CachedSubscription, 0) for i := amount; i > 0; i-- { - cs := functions.CachedSubscription{ + cs := subscriptions.CachedSubscription{ SubscriptionID: uint64(i), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -51,19 +51,6 @@ func seedSubscriptions(t *testing.T, orm functions.ORM, amount int) []functions. return storedSubscriptions } -func seedAllowedSenders(t *testing.T, orm functions.ORM, amount int) []common.Address { - storedAllowedSenders := make([]common.Address, amount) - for i := 0; i < amount; i++ { - address := testutils.NewAddress() - storedAllowedSenders[i] = address - } - - err := orm.CreateAllowedSenders(storedAllowedSenders) - require.NoError(t, err) - - return storedAllowedSenders -} - func TestORM_GetSubscriptions(t *testing.T) { t.Parallel() t.Run("fetch first page", func(t *testing.T) { @@ -93,7 +80,7 @@ func TestORM_UpsertSubscription(t *testing.T) { t.Run("create a subscription", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - expected := functions.CachedSubscription{ + expected := subscriptions.CachedSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -117,7 +104,7 @@ func TestORM_UpsertSubscription(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - expectedUpdated := functions.CachedSubscription{ + expectedUpdated := subscriptions.CachedSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -131,7 +118,7 @@ func TestORM_UpsertSubscription(t *testing.T) { err = orm.UpsertSubscription(expectedUpdated) require.NoError(t, err) - expectedNotUpdated := functions.CachedSubscription{ + expectedNotUpdated := subscriptions.CachedSubscription{ SubscriptionID: uint64(2), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -161,7 +148,7 @@ func TestORM_UpsertSubscription(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - subscription := functions.CachedSubscription{ + subscription := subscriptions.CachedSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -200,12 +187,12 @@ func TestORM_UpsertSubscription(t *testing.T) { lggr = logger.TestLogger(t) ) - orm1, err := functions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) + orm1, err := subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) require.NoError(t, err) - orm2, err := functions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) + orm2, err := subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) require.NoError(t, err) - subscription := functions.CachedSubscription{ + subscription := subscriptions.CachedSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: assets.Ether(10).ToInt(), @@ -242,106 +229,17 @@ func TestORM_UpsertSubscription(t *testing.T) { require.Equal(t, 1, len(results), "incorrect results length") }) } - -func TestORM_GetAllowedSenders(t *testing.T) { - t.Parallel() - t.Run("fetch first page", func(t *testing.T) { - orm, err := setupORM(t) - require.NoError(t, err) - storedAllowedSenders := seedAllowedSenders(t, orm, 2) - results, err := orm.GetAllowedSenders(0, 1) - require.NoError(t, err) - require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, storedAllowedSenders[0], results[0]) - }) - - t.Run("fetch second page", func(t *testing.T) { - orm, err := setupORM(t) - require.NoError(t, err) - storedAllowedSenders := seedAllowedSenders(t, orm, 2) - results, err := orm.GetAllowedSenders(1, 5) - require.NoError(t, err) - require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, storedAllowedSenders[1], results[0]) - }) -} - -func TestORM_CreateAllowedSenders(t *testing.T) { - t.Parallel() - - t.Run("OK-create_an_allowed_sender", func(t *testing.T) { - orm, err := setupORM(t) - require.NoError(t, err) - expected := testutils.NewAddress() - err = orm.CreateAllowedSenders([]common.Address{expected}) - require.NoError(t, err) - - results, err := orm.GetAllowedSenders(0, 1) - require.NoError(t, err) - require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, expected, results[0]) - }) - - t.Run("OK-create_an_existing_allowed_sender", func(t *testing.T) { - orm, err := setupORM(t) - require.NoError(t, err) - expected := testutils.NewAddress() - err = orm.CreateAllowedSenders([]common.Address{expected}) - require.NoError(t, err) - - err = orm.CreateAllowedSenders([]common.Address{expected}) - require.NoError(t, err) - - results, err := orm.GetAllowedSenders(0, 5) - require.NoError(t, err) - require.Equal(t, 1, len(results), "incorrect results length") - require.Equal(t, expected, results[0]) - }) - - t.Run("OK-create_multiple_allowed_senders_in_one_query", func(t *testing.T) { - orm, err := setupORM(t) - require.NoError(t, err) - expected := []common.Address{testutils.NewAddress(), testutils.NewAddress()} - err = orm.CreateAllowedSenders(expected) - require.NoError(t, err) - - results, err := orm.GetAllowedSenders(0, 2) - require.NoError(t, err) - require.Equal(t, 2, len(results), "incorrect results length") - require.Equal(t, expected[0], results[0]) - require.Equal(t, expected[1], results[1]) - }) - - t.Run("OK-create_multiple_allowed_senders_with_duplicates", func(t *testing.T) { - orm, err := setupORM(t) - require.NoError(t, err) - addr1 := testutils.NewAddress() - addr2 := testutils.NewAddress() - expected := []common.Address{addr1, addr2} - - duplicatedAddressInput := []common.Address{addr1, addr1, addr1, addr2} - err = orm.CreateAllowedSenders(duplicatedAddressInput) - require.NoError(t, err) - - results, err := orm.GetAllowedSenders(0, 10) - require.NoError(t, err) - require.Equal(t, 2, len(results), "incorrect results length") - require.Equal(t, expected[0], results[0]) - require.Equal(t, expected[1], results[1]) - }) -} - func Test_NewORM(t *testing.T) { t.Run("OK-create_ORM", func(t *testing.T) { - _, err := functions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress()) + _, err := subscriptions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress()) require.NoError(t, err) }) t.Run("NOK-create_ORM_with_nil_fields", func(t *testing.T) { - _, err := functions.NewORM(nil, nil, nil, common.Address{}) + _, err := subscriptions.NewORM(nil, nil, nil, common.Address{}) require.Error(t, err) }) t.Run("NOK-create_ORM_with_empty_address", func(t *testing.T) { - _, err := functions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), common.Address{}) + _, err := subscriptions.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), common.Address{}) require.Error(t, err) }) } diff --git a/core/services/gateway/handlers/functions/subscriptions.go b/core/services/gateway/handlers/functions/subscriptions/subscriptions.go similarity index 99% rename from core/services/gateway/handlers/functions/subscriptions.go rename to core/services/gateway/handlers/functions/subscriptions/subscriptions.go index 8bc9cf09e7b..c21e2dc5bef 100644 --- a/core/services/gateway/handlers/functions/subscriptions.go +++ b/core/services/gateway/handlers/functions/subscriptions/subscriptions.go @@ -1,4 +1,4 @@ -package functions +package subscriptions import ( "context" diff --git a/core/services/gateway/handlers/functions/subscriptions_test.go b/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go similarity index 91% rename from core/services/gateway/handlers/functions/subscriptions_test.go rename to core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go index 782dcc2332d..94cd1f424e8 100644 --- a/core/services/gateway/handlers/functions/subscriptions_test.go +++ b/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go @@ -1,4 +1,4 @@ -package functions_test +package subscriptions_test import ( "math/big" @@ -18,8 +18,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" - fmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" + smocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions/mocks" ) const ( @@ -43,17 +43,17 @@ func TestSubscriptions_OnePass(t *testing.T) { To: &common.Address{}, Data: hexutil.MustDecode("0xec2454e500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"), }, mock.Anything).Return(getSubscriptionsInRange, nil) - config := functions.OnchainSubscriptionsConfig{ + config := subscriptions.OnchainSubscriptionsConfig{ ContractAddress: common.Address{}, BlockConfirmations: 1, UpdateFrequencySec: 1, UpdateTimeoutSec: 1, UpdateRangeSize: 3, } - orm := fmocks.NewORM(t) - orm.On("GetSubscriptions", uint(0), uint(100)).Return([]functions.CachedSubscription{}, nil) + orm := smocks.NewORM(t) + orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.CachedSubscription{}, nil) orm.On("UpsertSubscription", mock.Anything).Return(nil) - subscriptions, err := functions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) + subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = subscriptions.Start(ctx) @@ -94,17 +94,17 @@ func TestSubscriptions_MultiPass(t *testing.T) { To: &common.Address{}, Data: hexutil.MustDecode("0xec2454e500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006"), }, mock.Anything).Return(getSubscriptionsInRange, nil) - config := functions.OnchainSubscriptionsConfig{ + config := subscriptions.OnchainSubscriptionsConfig{ ContractAddress: common.Address{}, BlockConfirmations: 1, UpdateFrequencySec: 1, UpdateTimeoutSec: 1, UpdateRangeSize: 3, } - orm := fmocks.NewORM(t) - orm.On("GetSubscriptions", uint(0), uint(100)).Return([]functions.CachedSubscription{}, nil) + orm := smocks.NewORM(t) + orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.CachedSubscription{}, nil) orm.On("UpsertSubscription", mock.Anything).Return(nil) - subscriptions, err := functions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) + subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = subscriptions.Start(ctx) @@ -133,7 +133,7 @@ func TestSubscriptions_Cached(t *testing.T) { To: &common.Address{}, Data: hexutil.MustDecode("0xec2454e500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003"), }, mock.Anything).Return(getSubscriptionsInRange, nil) - config := functions.OnchainSubscriptionsConfig{ + config := subscriptions.OnchainSubscriptionsConfig{ ContractAddress: common.Address{}, BlockConfirmations: 1, UpdateFrequencySec: 1, @@ -143,8 +143,8 @@ func TestSubscriptions_Cached(t *testing.T) { } expectedBalance := big.NewInt(5) - orm := fmocks.NewORM(t) - orm.On("GetSubscriptions", uint(0), uint(1)).Return([]functions.CachedSubscription{ + orm := smocks.NewORM(t) + orm.On("GetSubscriptions", uint(0), uint(1)).Return([]subscriptions.CachedSubscription{ { SubscriptionID: 1, IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ @@ -154,10 +154,10 @@ func TestSubscriptions_Cached(t *testing.T) { }, }, }, nil) - orm.On("GetSubscriptions", uint(1), uint(1)).Return([]functions.CachedSubscription{}, nil) + orm.On("GetSubscriptions", uint(1), uint(1)).Return([]subscriptions.CachedSubscription{}, nil) orm.On("UpsertSubscription", mock.Anything).Return(nil) - subscriptions, err := functions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) + subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) err = subscriptions.Start(ctx) diff --git a/core/services/gateway/handlers/functions/user_subscriptions.go b/core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go similarity index 99% rename from core/services/gateway/handlers/functions/user_subscriptions.go rename to core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go index 7e63720da71..2835fe6c89c 100644 --- a/core/services/gateway/handlers/functions/user_subscriptions.go +++ b/core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go @@ -1,4 +1,4 @@ -package functions +package subscriptions import ( "math/big" diff --git a/core/services/gateway/handlers/functions/user_subscriptions_test.go b/core/services/gateway/handlers/functions/subscriptions/user_subscriptions_test.go similarity index 92% rename from core/services/gateway/handlers/functions/user_subscriptions_test.go rename to core/services/gateway/handlers/functions/subscriptions/user_subscriptions_test.go index 53827e07e1b..4d58155735f 100644 --- a/core/services/gateway/handlers/functions/user_subscriptions_test.go +++ b/core/services/gateway/handlers/functions/subscriptions/user_subscriptions_test.go @@ -1,4 +1,4 @@ -package functions_test +package subscriptions_test import ( "math/big" @@ -6,7 +6,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/functions/generated/functions_router" - "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" "github.com/stretchr/testify/assert" ) @@ -14,7 +14,7 @@ import ( func TestUserSubscriptions(t *testing.T) { t.Parallel() - us := functions.NewUserSubscriptions() + us := subscriptions.NewUserSubscriptions() t.Run("GetMaxUserBalance for unknown user", func(t *testing.T) { _, err := us.GetMaxUserBalance(utils.RandomAddress()) @@ -60,7 +60,7 @@ func TestUserSubscriptions_UpdateSubscription(t *testing.T) { t.Parallel() t.Run("update balance", func(t *testing.T) { - us := functions.NewUserSubscriptions() + us := subscriptions.NewUserSubscriptions() owner := utils.RandomAddress() updated := us.UpdateSubscription(1, &functions_router.IFunctionsSubscriptionsSubscription{ @@ -77,7 +77,7 @@ func TestUserSubscriptions_UpdateSubscription(t *testing.T) { }) t.Run("updated proposed owner", func(t *testing.T) { - us := functions.NewUserSubscriptions() + us := subscriptions.NewUserSubscriptions() owner := utils.RandomAddress() updated := us.UpdateSubscription(1, &functions_router.IFunctionsSubscriptionsSubscription{ @@ -94,7 +94,7 @@ func TestUserSubscriptions_UpdateSubscription(t *testing.T) { assert.True(t, updated) }) t.Run("remove subscriptions", func(t *testing.T) { - us := functions.NewUserSubscriptions() + us := subscriptions.NewUserSubscriptions() user2 := utils.RandomAddress() user2Balance1 := big.NewInt(50) user2Balance2 := big.NewInt(70) @@ -126,7 +126,7 @@ func TestUserSubscriptions_UpdateSubscription(t *testing.T) { }) t.Run("remove a non existing subscription", func(t *testing.T) { - us := functions.NewUserSubscriptions() + us := subscriptions.NewUserSubscriptions() updated := us.UpdateSubscription(3, &functions_router.IFunctionsSubscriptionsSubscription{ Owner: utils.ZeroAddress, }) @@ -134,7 +134,7 @@ func TestUserSubscriptions_UpdateSubscription(t *testing.T) { }) t.Run("no actual changes", func(t *testing.T) { - us := functions.NewUserSubscriptions() + us := subscriptions.NewUserSubscriptions() subscription := &functions_router.IFunctionsSubscriptionsSubscription{ Owner: utils.RandomAddress(), Balance: big.NewInt(25), diff --git a/core/services/ocr2/plugins/functions/config/config.go b/core/services/ocr2/plugins/functions/config/config.go index 38af7b8587f..e0e1ba3bfa0 100644 --- a/core/services/ocr2/plugins/functions/config/config.go +++ b/core/services/ocr2/plugins/functions/config/config.go @@ -13,41 +13,42 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" - "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" s4PluginConfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/s4" "github.com/smartcontractkit/chainlink/v2/core/services/s4" ) // This config is part of the job spec and is loaded only once on node boot/job creation. type PluginConfig struct { - EnableRequestSignatureCheck bool `json:"enableRequestSignatureCheck"` - DONID string `json:"donID"` - ContractVersion uint32 `json:"contractVersion"` - MinRequestConfirmations uint32 `json:"minRequestConfirmations"` - MinResponseConfirmations uint32 `json:"minResponseConfirmations"` - MinIncomingConfirmations uint32 `json:"minIncomingConfirmations"` - PastBlocksToPoll uint32 `json:"pastBlocksToPoll"` - LogPollerCacheDurationSec uint32 `json:"logPollerCacheDurationSec"` // Duration to cache previously detected request or response logs such that they can be filtered when calling logpoller_wrapper.LatestEvents() - RequestTimeoutSec uint32 `json:"requestTimeoutSec"` - RequestTimeoutCheckFrequencySec uint32 `json:"requestTimeoutCheckFrequencySec"` - RequestTimeoutBatchLookupSize uint32 `json:"requestTimeoutBatchLookupSize"` - PruneMaxStoredRequests uint32 `json:"pruneMaxStoredRequests"` - PruneCheckFrequencySec uint32 `json:"pruneCheckFrequencySec"` - PruneBatchSize uint32 `json:"pruneBatchSize"` - ListenerEventHandlerTimeoutSec uint32 `json:"listenerEventHandlerTimeoutSec"` - ListenerEventsCheckFrequencyMillis uint32 `json:"listenerEventsCheckFrequencyMillis"` - ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"` - MaxRequestSizeBytes uint32 `json:"maxRequestSizeBytes"` - MaxRequestSizesList []uint32 `json:"maxRequestSizesList"` - MaxSecretsSizesList []uint32 `json:"maxSecretsSizesList"` - MinimumSubscriptionBalance assets.Link `json:"minimumSubscriptionBalance"` - AllowedHeartbeatInitiators []string `json:"allowedHeartbeatInitiators"` - GatewayConnectorConfig *connector.ConnectorConfig `json:"gatewayConnectorConfig"` - OnchainAllowlist *functions.OnchainAllowlistConfig `json:"onchainAllowlist"` - OnchainSubscriptions *functions.OnchainSubscriptionsConfig `json:"onchainSubscriptions"` - RateLimiter *common.RateLimiterConfig `json:"rateLimiter"` - S4Constraints *s4.Constraints `json:"s4Constraints"` - DecryptionQueueConfig *DecryptionQueueConfig `json:"decryptionQueueConfig"` + EnableRequestSignatureCheck bool `json:"enableRequestSignatureCheck"` + DONID string `json:"donID"` + ContractVersion uint32 `json:"contractVersion"` + MinRequestConfirmations uint32 `json:"minRequestConfirmations"` + MinResponseConfirmations uint32 `json:"minResponseConfirmations"` + MinIncomingConfirmations uint32 `json:"minIncomingConfirmations"` + PastBlocksToPoll uint32 `json:"pastBlocksToPoll"` + LogPollerCacheDurationSec uint32 `json:"logPollerCacheDurationSec"` // Duration to cache previously detected request or response logs such that they can be filtered when calling logpoller_wrapper.LatestEvents() + RequestTimeoutSec uint32 `json:"requestTimeoutSec"` + RequestTimeoutCheckFrequencySec uint32 `json:"requestTimeoutCheckFrequencySec"` + RequestTimeoutBatchLookupSize uint32 `json:"requestTimeoutBatchLookupSize"` + PruneMaxStoredRequests uint32 `json:"pruneMaxStoredRequests"` + PruneCheckFrequencySec uint32 `json:"pruneCheckFrequencySec"` + PruneBatchSize uint32 `json:"pruneBatchSize"` + ListenerEventHandlerTimeoutSec uint32 `json:"listenerEventHandlerTimeoutSec"` + ListenerEventsCheckFrequencyMillis uint32 `json:"listenerEventsCheckFrequencyMillis"` + ContractUpdateCheckFrequencySec uint32 `json:"contractUpdateCheckFrequencySec"` + MaxRequestSizeBytes uint32 `json:"maxRequestSizeBytes"` + MaxRequestSizesList []uint32 `json:"maxRequestSizesList"` + MaxSecretsSizesList []uint32 `json:"maxSecretsSizesList"` + MinimumSubscriptionBalance assets.Link `json:"minimumSubscriptionBalance"` + AllowedHeartbeatInitiators []string `json:"allowedHeartbeatInitiators"` + GatewayConnectorConfig *connector.ConnectorConfig `json:"gatewayConnectorConfig"` + OnchainAllowlist *allowlist.OnchainAllowlistConfig `json:"onchainAllowlist"` + OnchainSubscriptions *subscriptions.OnchainSubscriptionsConfig `json:"onchainSubscriptions"` + RateLimiter *common.RateLimiterConfig `json:"rateLimiter"` + S4Constraints *s4.Constraints `json:"s4Constraints"` + DecryptionQueueConfig *DecryptionQueueConfig `json:"decryptionQueueConfig"` } type DecryptionQueueConfig struct { diff --git a/core/services/ocr2/plugins/functions/plugin.go b/core/services/ocr2/plugins/functions/plugin.go index 6c4f323c07a..15e36f07b09 100644 --- a/core/services/ocr2/plugins/functions/plugin.go +++ b/core/services/ocr2/plugins/functions/plugin.go @@ -21,7 +21,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/functions" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" - gwFunctions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" + gwAllowlist "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" + gwSubscriptions "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" @@ -134,11 +135,11 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs allServices = append(allServices, job.NewServiceAdapter(functionsReportingPluginOracle)) if pluginConfig.GatewayConnectorConfig != nil && s4Storage != nil && pluginConfig.OnchainAllowlist != nil && pluginConfig.RateLimiter != nil && pluginConfig.OnchainSubscriptions != nil { - gwFunctionsORM, err := gwFunctions.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainSubscriptions.ContractAddress) + allowlistORM, err := gwAllowlist.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainAllowlist.ContractAddress) if err != nil { - return nil, errors.Wrap(err, "failed to create functions ORM") + return nil, errors.Wrap(err, "failed to create allowlist ORM") } - allowlist, err2 := gwFunctions.NewOnchainAllowlist(conf.Chain.Client(), *pluginConfig.OnchainAllowlist, gwFunctionsORM, conf.Logger) + allowlist, err2 := gwAllowlist.NewOnchainAllowlist(conf.Chain.Client(), *pluginConfig.OnchainAllowlist, allowlistORM, conf.Logger) if err2 != nil { return nil, errors.Wrap(err, "failed to create OnchainAllowlist") } @@ -146,7 +147,11 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs if err2 != nil { return nil, errors.Wrap(err, "failed to create a RateLimiter") } - subscriptions, err2 := gwFunctions.NewOnchainSubscriptions(conf.Chain.Client(), *pluginConfig.OnchainSubscriptions, gwFunctionsORM, conf.Logger) + subscriptionsORM, err := gwSubscriptions.NewORM(conf.DB, conf.Logger, conf.QConfig, pluginConfig.OnchainSubscriptions.ContractAddress) + if err != nil { + return nil, errors.Wrap(err, "failed to create subscriptions ORM") + } + subscriptions, err2 := gwSubscriptions.NewOnchainSubscriptions(conf.Chain.Client(), *pluginConfig.OnchainSubscriptions, subscriptionsORM, conf.Logger) if err2 != nil { return nil, errors.Wrap(err, "failed to create a OnchainSubscriptions") } @@ -178,7 +183,7 @@ func NewFunctionsServices(functionsOracleArgs, thresholdOracleArgs, s4OracleArgs return allServices, nil } -func NewConnector(pluginConfig *config.PluginConfig, ethKeystore keystore.Eth, chainID *big.Int, s4Storage s4.Storage, allowlist gwFunctions.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions gwFunctions.OnchainSubscriptions, listener functions.FunctionsListener, offchainTransmitter functions.OffchainTransmitter, lggr logger.Logger) (connector.GatewayConnector, error) { +func NewConnector(pluginConfig *config.PluginConfig, ethKeystore keystore.Eth, chainID *big.Int, s4Storage s4.Storage, allowlist gwAllowlist.OnchainAllowlist, rateLimiter *hc.RateLimiter, subscriptions gwSubscriptions.OnchainSubscriptions, listener functions.FunctionsListener, offchainTransmitter functions.OffchainTransmitter, lggr logger.Logger) (connector.GatewayConnector, error) { enabledKeys, err := ethKeystore.EnabledKeysForChain(chainID) if err != nil { return nil, err diff --git a/core/services/ocr2/plugins/functions/plugin_test.go b/core/services/ocr2/plugins/functions/plugin_test.go index 6d3f57b086c..cd7956240df 100644 --- a/core/services/ocr2/plugins/functions/plugin_test.go +++ b/core/services/ocr2/plugins/functions/plugin_test.go @@ -12,7 +12,8 @@ import ( sfmocks "github.com/smartcontractkit/chainlink/v2/core/services/functions/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" - gfmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/mocks" + gfaMocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist/mocks" + gfsMocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" ksmocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions" @@ -32,8 +33,8 @@ func TestNewConnector_Success(t *testing.T) { chainID := big.NewInt(80001) ethKeystore := ksmocks.NewEth(t) s4Storage := s4mocks.NewStorage(t) - allowlist := gfmocks.NewOnchainAllowlist(t) - subscriptions := gfmocks.NewOnchainSubscriptions(t) + allowlist := gfaMocks.NewOnchainAllowlist(t) + subscriptions := gfsMocks.NewOnchainSubscriptions(t) rateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100}) require.NoError(t, err) listener := sfmocks.NewFunctionsListener(t) @@ -60,8 +61,8 @@ func TestNewConnector_NoKeyForConfiguredAddress(t *testing.T) { chainID := big.NewInt(80001) ethKeystore := ksmocks.NewEth(t) s4Storage := s4mocks.NewStorage(t) - allowlist := gfmocks.NewOnchainAllowlist(t) - subscriptions := gfmocks.NewOnchainSubscriptions(t) + allowlist := gfaMocks.NewOnchainAllowlist(t) + subscriptions := gfsMocks.NewOnchainSubscriptions(t) rateLimiter, err := hc.NewRateLimiter(hc.RateLimiterConfig{GlobalRPS: 100.0, GlobalBurst: 100, PerSenderRPS: 100.0, PerSenderBurst: 100}) require.NoError(t, err) listener := sfmocks.NewFunctionsListener(t) From ab8dec7868787493bd388a9d1795c64f18d5b6bc Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Wed, 17 Jan 2024 15:02:22 +0100 Subject: [PATCH 15/23] feat: put the new functionality under a feature flag --- .../handlers/functions/allowlist/allowlist.go | 76 +++++++++++-------- .../functions/allowlist/allowlist_test.go | 36 ++++++++- 2 files changed, 81 insertions(+), 31 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go index 5bfe78a968b..8f3bbe7aad1 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -34,12 +34,14 @@ type OnchainAllowlistConfig struct { ContractVersion uint32 `json:"contractVersion"` BlockConfirmations uint `json:"blockConfirmations"` // UpdateFrequencySec can be zero to disable periodic updates - UpdateFrequencySec uint `json:"updateFrequencySec"` - UpdateTimeoutSec uint `json:"updateTimeoutSec"` - // FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist. - FetchingDelayInRangeSec uint `json:"fetchingDelayInRangeSec"` + UpdateFrequencySec uint `json:"updateFrequencySec"` + UpdateTimeoutSec uint `json:"updateTimeoutSec"` StoredAllowlistBatchSize uint `json:"storedAllowlistBatchSize"` OnchainAllowlistBatchSize uint `json:"onchainAllowlistBatchSize"` + // FetchingInRangeEnabled is a feature flag that enables fetching allowlist by batches + FetchingInRangeEnabled bool `json:"fetchingInRangeEnabled"` + // FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist. + FetchingDelayInRangeSec uint `json:"fetchingDelayInRangeSec"` } // OnchainAllowlist maintains an allowlist of addresses fetched from the blockchain (EVM-only). @@ -202,43 +204,57 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b if err != nil { return errors.Wrap(err, "unexpected error during functions_allow_list.NewTermsOfServiceAllowList") } - - count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ - Pending: false, - BlockNumber: blockNum, - Context: ctx, - }) - if err != nil { - return errors.Wrap(err, "unexpected error during functions_allow_list.GetAllowedSendersCount") - } - allowedSenderList := make([]common.Address, 0) - throttleTicker := time.NewTicker(time.Duration(a.config.FetchingDelayInRangeSec) * time.Second) - for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { - <-throttleTicker.C - - idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) - if idxEnd >= count { - idxEnd = count - 1 - } - - allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ + if !a.config.FetchingInRangeEnabled { + allowedSenderList, err = tosContract.GetAllAllowedSenders(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, Context: ctx, - }, idxStart, idxEnd) + }) if err != nil { - return errors.Wrap(err, "error calling GetAllowedSendersInRange") + return errors.Wrap(err, "error calling GetAllAllowedSenders") } - - allowedSenderList = append(allowedSenderList, allowedSendersBatch...) - err = a.orm.CreateAllowedSenders(allowedSendersBatch) + err = a.orm.CreateAllowedSenders(allowedSenderList) if err != nil { a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) } + } else { + count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }) + if err != nil { + return errors.Wrap(err, "unexpected error during functions_allow_list.GetAllowedSendersCount") + } + + throttleTicker := time.NewTicker(time.Duration(a.config.FetchingDelayInRangeSec) * time.Second) + for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { + <-throttleTicker.C + + idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) + if idxEnd >= count { + idxEnd = count - 1 + } + + allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }, idxStart, idxEnd) + if err != nil { + return errors.Wrap(err, "error calling GetAllowedSendersInRange") + } + + allowedSenderList = append(allowedSenderList, allowedSendersBatch...) + err = a.orm.CreateAllowedSenders(allowedSendersBatch) + if err != nil { + a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) + } + } + throttleTicker.Stop() } - throttleTicker.Stop() a.update(allowedSenderList) return nil diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go index a1d474d97e1..96014711f77 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -134,7 +134,41 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { UpdateFrequencySec: 1, UpdateTimeoutSec: 1, StoredAllowlistBatchSize: 2, - OnchainAllowlistBatchSize: 32, + OnchainAllowlistBatchSize: 16, + FetchingInRangeEnabled: true, + FetchingDelayInRangeSec: 0, + } + + orm := amocks.NewORM(t) + orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) + + allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) + require.NoError(t, err) + + err = allowlist.UpdateFromContract(ctx) + require.NoError(t, err) + + gomega.NewGomegaWithT(t).Eventually(func() bool { + return allowlist.Allow(common.HexToAddress(addr1)) && !allowlist.Allow(common.HexToAddress(addr3)) + }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) + }) + + t.Run("OK-fetch_complete_list_of_allowed_senders", func(t *testing.T) { + ctx, cancel := context.WithCancel(testutils.Context(t)) + client := mocks.NewClient(t) + client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) + client.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Run(func(args mock.Arguments) { + cancel() + }).Return(sampleEncodedAllowlist(t), nil) + config := allowlist.OnchainAllowlistConfig{ + ContractAddress: common.HexToAddress(addr3), + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 1, + UpdateTimeoutSec: 1, + StoredAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 16, + FetchingInRangeEnabled: false, FetchingDelayInRangeSec: 0, } From d796d7f68c758b6dd80e2a6e3173dcb16e92c198 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Thu, 18 Jan 2024 12:20:20 +0100 Subject: [PATCH 16/23] fix: fix subscriptions consumers address --- .../gateway/handlers/functions/subscriptions/orm.go | 7 ++++++- .../gateway/handlers/functions/subscriptions/orm_test.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/services/gateway/handlers/functions/subscriptions/orm.go b/core/services/gateway/handlers/functions/subscriptions/orm.go index 297713325a0..b97f68fc90d 100644 --- a/core/services/gateway/handlers/functions/subscriptions/orm.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm.go @@ -98,6 +98,11 @@ func (o *orm) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QO subscription.BlockedBalance = big.NewInt(0) } + var consumers [][]byte + for _, c := range subscription.Consumers { + consumers = append(consumers, c.Bytes()) + } + _, err := o.q.WithOpts(qopts...).Exec( stmt, subscription.SubscriptionID, @@ -105,7 +110,7 @@ func (o *orm) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QO subscription.Balance.Int64(), subscription.BlockedBalance.Int64(), subscription.ProposedOwner, - subscription.Consumers, + consumers, subscription.Flags[:], o.routerContractAddress, ) diff --git a/core/services/gateway/handlers/functions/subscriptions/orm_test.go b/core/services/gateway/handlers/functions/subscriptions/orm_test.go index f7720fe678c..909cf30eb81 100644 --- a/core/services/gateway/handlers/functions/subscriptions/orm_test.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm_test.go @@ -87,7 +87,7 @@ func TestORM_UpsertSubscription(t *testing.T) { Owner: testutils.NewAddress(), BlockedBalance: big.NewInt(20), ProposedOwner: common.Address{}, - Consumers: []common.Address{}, + Consumers: []common.Address{testutils.NewAddress()}, Flags: defaultFlags, }, } From 1be1f8ab2c9818b26961943c23f6ca6ffeb09b65 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Thu, 18 Jan 2024 14:52:47 +0100 Subject: [PATCH 17/23] fix: store only on feature enable to prevent blocked addresses not being sync --- .../handlers/functions/allowlist/allowlist.go | 12 ++---- .../functions/allowlist/allowlist_test.go | 43 ++++++++----------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go index 8f3bbe7aad1..51737fa0228 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -38,9 +38,9 @@ type OnchainAllowlistConfig struct { UpdateTimeoutSec uint `json:"updateTimeoutSec"` StoredAllowlistBatchSize uint `json:"storedAllowlistBatchSize"` OnchainAllowlistBatchSize uint `json:"onchainAllowlistBatchSize"` - // FetchingInRangeEnabled is a feature flag that enables fetching allowlist by batches - FetchingInRangeEnabled bool `json:"fetchingInRangeEnabled"` - // FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist. + // StoreAllowedSendersEnabled is a feature flag that enables storing in db a copy of the allowlist. + StoreAllowedSendersEnabled bool `json:"storeAllowedSendersEnabled"` + // FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist in ranges. FetchingDelayInRangeSec uint `json:"fetchingDelayInRangeSec"` } @@ -206,7 +206,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b } allowedSenderList := make([]common.Address, 0) - if !a.config.FetchingInRangeEnabled { + if !a.config.StoreAllowedSendersEnabled { allowedSenderList, err = tosContract.GetAllAllowedSenders(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, @@ -215,10 +215,6 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b if err != nil { return errors.Wrap(err, "error calling GetAllAllowedSenders") } - err = a.orm.CreateAllowedSenders(allowedSenderList) - if err != nil { - a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) - } } else { count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ Pending: false, diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go index 96014711f77..f2596da8591 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -50,8 +50,6 @@ func TestAllowlist_UpdateAndCheck(t *testing.T) { } orm := amocks.NewORM(t) - orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) - allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -102,7 +100,6 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { orm := amocks.NewORM(t) orm.On("GetAllowedSenders", uint(0), uint(1000)).Return([]common.Address{}, nil) - orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Return(nil) allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -128,15 +125,15 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { cancel() }).Return(sampleEncodedAllowlist(t), nil) config := allowlist.OnchainAllowlistConfig{ - ContractAddress: common.HexToAddress(addr3), - ContractVersion: 1, - BlockConfirmations: 1, - UpdateFrequencySec: 1, - UpdateTimeoutSec: 1, - StoredAllowlistBatchSize: 2, - OnchainAllowlistBatchSize: 16, - FetchingInRangeEnabled: true, - FetchingDelayInRangeSec: 0, + ContractAddress: common.HexToAddress(addr3), + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 1, + UpdateTimeoutSec: 1, + StoredAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 16, + StoreAllowedSendersEnabled: true, + FetchingDelayInRangeSec: 0, } orm := amocks.NewORM(t) @@ -153,7 +150,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) }) - t.Run("OK-fetch_complete_list_of_allowed_senders", func(t *testing.T) { + t.Run("OK-fetch_complete_list_of_allowed_senders_without_storing", func(t *testing.T) { ctx, cancel := context.WithCancel(testutils.Context(t)) client := mocks.NewClient(t) client.On("LatestBlockHeight", mock.Anything).Return(big.NewInt(42), nil) @@ -161,20 +158,18 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { cancel() }).Return(sampleEncodedAllowlist(t), nil) config := allowlist.OnchainAllowlistConfig{ - ContractAddress: common.HexToAddress(addr3), - ContractVersion: 1, - BlockConfirmations: 1, - UpdateFrequencySec: 1, - UpdateTimeoutSec: 1, - StoredAllowlistBatchSize: 2, - OnchainAllowlistBatchSize: 16, - FetchingInRangeEnabled: false, - FetchingDelayInRangeSec: 0, + ContractAddress: common.HexToAddress(addr3), + ContractVersion: 1, + BlockConfirmations: 1, + UpdateFrequencySec: 1, + UpdateTimeoutSec: 1, + StoredAllowlistBatchSize: 2, + OnchainAllowlistBatchSize: 16, + StoreAllowedSendersEnabled: false, + FetchingDelayInRangeSec: 0, } orm := amocks.NewORM(t) - orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(1).Return(nil) - allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) From 93893027dc4f1450658c7f92a4ebb6e35a574655 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Thu, 18 Jan 2024 16:38:35 +0100 Subject: [PATCH 18/23] chore: rename CachedSubscriptions to StoredSubscriptions --- .../functions/subscriptions/mocks/orm.go | 14 ++++----- .../handlers/functions/subscriptions/orm.go | 30 +++++++++---------- .../functions/subscriptions/orm_test.go | 16 +++++----- .../functions/subscriptions/subscriptions.go | 28 ++++++++--------- .../subscriptions/subscriptions_test.go | 18 +++++------ .../subscriptions/user_subscriptions.go | 4 +-- 6 files changed, 55 insertions(+), 55 deletions(-) diff --git a/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go b/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go index a4406c4fda1..0f278aa49b0 100644 --- a/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go +++ b/core/services/gateway/handlers/functions/subscriptions/mocks/orm.go @@ -14,7 +14,7 @@ type ORM struct { } // GetSubscriptions provides a mock function with given fields: offset, limit, qopts -func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]subscriptions.CachedSubscription, error) { +func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]subscriptions.StoredSubscription, error) { _va := make([]interface{}, len(qopts)) for _i := range qopts { _va[_i] = qopts[_i] @@ -28,16 +28,16 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]su panic("no return value specified for GetSubscriptions") } - var r0 []subscriptions.CachedSubscription + var r0 []subscriptions.StoredSubscription var r1 error - if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]subscriptions.CachedSubscription, error)); ok { + if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) ([]subscriptions.StoredSubscription, error)); ok { return rf(offset, limit, qopts...) } - if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []subscriptions.CachedSubscription); ok { + if rf, ok := ret.Get(0).(func(uint, uint, ...pg.QOpt) []subscriptions.StoredSubscription); ok { r0 = rf(offset, limit, qopts...) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]subscriptions.CachedSubscription) + r0 = ret.Get(0).([]subscriptions.StoredSubscription) } } @@ -51,7 +51,7 @@ func (_m *ORM) GetSubscriptions(offset uint, limit uint, qopts ...pg.QOpt) ([]su } // UpsertSubscription provides a mock function with given fields: subscription, qopts -func (_m *ORM) UpsertSubscription(subscription subscriptions.CachedSubscription, qopts ...pg.QOpt) error { +func (_m *ORM) UpsertSubscription(subscription subscriptions.StoredSubscription, qopts ...pg.QOpt) error { _va := make([]interface{}, len(qopts)) for _i := range qopts { _va[_i] = qopts[_i] @@ -66,7 +66,7 @@ func (_m *ORM) UpsertSubscription(subscription subscriptions.CachedSubscription, } var r0 error - if rf, ok := ret.Get(0).(func(subscriptions.CachedSubscription, ...pg.QOpt) error); ok { + if rf, ok := ret.Get(0).(func(subscriptions.StoredSubscription, ...pg.QOpt) error); ok { r0 = rf(subscription, qopts...) } else { r0 = ret.Error(0) diff --git a/core/services/gateway/handlers/functions/subscriptions/orm.go b/core/services/gateway/handlers/functions/subscriptions/orm.go index b97f68fc90d..5ef09403708 100644 --- a/core/services/gateway/handlers/functions/subscriptions/orm.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm.go @@ -17,8 +17,8 @@ import ( //go:generate mockery --quiet --name ORM --output ./mocks/ --case=underscore type ORM interface { - GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSubscription, error) - UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error + GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]StoredSubscription, error) + UpsertSubscription(subscription StoredSubscription, qopts ...pg.QOpt) error } type orm struct { @@ -29,14 +29,14 @@ type orm struct { var _ ORM = (*orm)(nil) var ( - ErrInvalidParameters = errors.New("invalid parameters provided to create a functions contract cache ORM") + ErrInvalidParameters = errors.New("invalid parameters provided to create a subscription contract ORM") ) const ( tableName = "functions_subscriptions" ) -type cachedSubscriptionRow struct { +type storedSubscriptionRow struct { SubscriptionID uint64 Owner common.Address Balance int64 @@ -59,9 +59,9 @@ func NewORM(db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig, routerContractAddre }, nil } -func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSubscription, error) { - var cacheSubscriptions []CachedSubscription - var cacheSubscriptionRows []cachedSubscriptionRow +func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]StoredSubscription, error) { + var storedSubscriptions []StoredSubscription + var storedSubscriptionRows []storedSubscriptionRow stmt := fmt.Sprintf(` SELECT subscription_id, owner, balance, blocked_balance, proposed_owner, consumers, flags, router_contract_address FROM %s @@ -70,21 +70,21 @@ func (o *orm) GetSubscriptions(offset, limit uint, qopts ...pg.QOpt) ([]CachedSu OFFSET $2 LIMIT $3; `, tableName) - err := o.q.WithOpts(qopts...).Select(&cacheSubscriptionRows, stmt, o.routerContractAddress, offset, limit) + err := o.q.WithOpts(qopts...).Select(&storedSubscriptionRows, stmt, o.routerContractAddress, offset, limit) if err != nil { - return cacheSubscriptions, err + return storedSubscriptions, err } - for _, cs := range cacheSubscriptionRows { - cacheSubscriptions = append(cacheSubscriptions, cs.encode()) + for _, cs := range storedSubscriptionRows { + storedSubscriptions = append(storedSubscriptions, cs.encode()) } - return cacheSubscriptions, nil + return storedSubscriptions, nil } // UpsertSubscription will update if a subscription exists or create if it does not. // In case a subscription gets deleted we will update it with an owner address equal to 0x0. -func (o *orm) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QOpt) error { +func (o *orm) UpsertSubscription(subscription StoredSubscription, qopts ...pg.QOpt) error { stmt := fmt.Sprintf(` INSERT INTO %s (subscription_id, owner, balance, blocked_balance, proposed_owner, consumers, flags, router_contract_address) VALUES ($1,$2,$3,$4,$5,$6,$7,$8) ON CONFLICT (subscription_id, router_contract_address) DO UPDATE @@ -118,13 +118,13 @@ func (o *orm) UpsertSubscription(subscription CachedSubscription, qopts ...pg.QO return err } -func (cs *cachedSubscriptionRow) encode() CachedSubscription { +func (cs *storedSubscriptionRow) encode() StoredSubscription { consumers := make([]common.Address, 0) for _, csc := range cs.Consumers { consumers = append(consumers, common.BytesToAddress(csc)) } - return CachedSubscription{ + return StoredSubscription{ SubscriptionID: cs.SubscriptionID, IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(cs.Balance), diff --git a/core/services/gateway/handlers/functions/subscriptions/orm_test.go b/core/services/gateway/handlers/functions/subscriptions/orm_test.go index 909cf30eb81..6cb1146f03c 100644 --- a/core/services/gateway/handlers/functions/subscriptions/orm_test.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm_test.go @@ -30,10 +30,10 @@ func setupORM(t *testing.T) (subscriptions.ORM, error) { return subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) } -func seedSubscriptions(t *testing.T, orm subscriptions.ORM, amount int) []subscriptions.CachedSubscription { - storedSubscriptions := make([]subscriptions.CachedSubscription, 0) +func seedSubscriptions(t *testing.T, orm subscriptions.ORM, amount int) []subscriptions.StoredSubscription { + storedSubscriptions := make([]subscriptions.StoredSubscription, 0) for i := amount; i > 0; i-- { - cs := subscriptions.CachedSubscription{ + cs := subscriptions.StoredSubscription{ SubscriptionID: uint64(i), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -80,7 +80,7 @@ func TestORM_UpsertSubscription(t *testing.T) { t.Run("create a subscription", func(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - expected := subscriptions.CachedSubscription{ + expected := subscriptions.StoredSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -104,7 +104,7 @@ func TestORM_UpsertSubscription(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - expectedUpdated := subscriptions.CachedSubscription{ + expectedUpdated := subscriptions.StoredSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -118,7 +118,7 @@ func TestORM_UpsertSubscription(t *testing.T) { err = orm.UpsertSubscription(expectedUpdated) require.NoError(t, err) - expectedNotUpdated := subscriptions.CachedSubscription{ + expectedNotUpdated := subscriptions.StoredSubscription{ SubscriptionID: uint64(2), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -148,7 +148,7 @@ func TestORM_UpsertSubscription(t *testing.T) { orm, err := setupORM(t) require.NoError(t, err) - subscription := subscriptions.CachedSubscription{ + subscription := subscriptions.StoredSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: big.NewInt(10), @@ -192,7 +192,7 @@ func TestORM_UpsertSubscription(t *testing.T) { orm2, err := subscriptions.NewORM(db, lggr, pgtest.NewQConfig(true), testutils.NewAddress()) require.NoError(t, err) - subscription := subscriptions.CachedSubscription{ + subscription := subscriptions.StoredSubscription{ SubscriptionID: uint64(1), IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: assets.Ether(10).ToInt(), diff --git a/core/services/gateway/handlers/functions/subscriptions/subscriptions.go b/core/services/gateway/handlers/functions/subscriptions/subscriptions.go index c21e2dc5bef..610aaa1d7f1 100644 --- a/core/services/gateway/handlers/functions/subscriptions/subscriptions.go +++ b/core/services/gateway/handlers/functions/subscriptions/subscriptions.go @@ -19,7 +19,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -const defaultCacheBatchSize = 100 +const defaultStoreBatchSize = 100 type OnchainSubscriptionsConfig struct { ContractAddress common.Address `json:"contractAddress"` @@ -27,7 +27,7 @@ type OnchainSubscriptionsConfig struct { UpdateFrequencySec uint `json:"updateFrequencySec"` UpdateTimeoutSec uint `json:"updateTimeoutSec"` UpdateRangeSize uint `json:"updateRangeSize"` - CacheBatchSize uint `json:"cacheBatchSize"` + StoreBatchSize uint `json:"storeBatchSize"` } // OnchainSubscriptions maintains a mirror of all subscriptions fetched from the blockchain (EVM-only). @@ -68,10 +68,10 @@ func NewOnchainSubscriptions(client evmclient.Client, config OnchainSubscription return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err) } - // if CacheBatchSize is not specified use the default value - if config.CacheBatchSize == 0 { - lggr.Info("CacheBatchSize not specified, using default size: ", defaultCacheBatchSize) - config.CacheBatchSize = defaultCacheBatchSize + // if StoreBatchSize is not specified use the default value + if config.StoreBatchSize == 0 { + lggr.Info("StoreBatchSize not specified, using default size: ", defaultStoreBatchSize) + config.StoreBatchSize = defaultStoreBatchSize } return &onchainSubscriptions{ @@ -99,7 +99,7 @@ func (s *onchainSubscriptions) Start(ctx context.Context) error { return errors.New("OnchainSubscriptionsConfig.UpdateRangeSize must be greater than 0") } - s.loadCachedSubscriptions() + s.loadStoredSubscriptions() s.closeWait.Add(1) go s.queryLoop() @@ -206,11 +206,11 @@ func (s *onchainSubscriptions) querySubscriptionsRange(ctx context.Context, bloc subscription := subscription updated := s.subscriptions.UpdateSubscription(subscriptionId, &subscription) if updated { - if err = s.orm.UpsertSubscription(CachedSubscription{ + if err = s.orm.UpsertSubscription(StoredSubscription{ SubscriptionID: subscriptionId, IFunctionsSubscriptionsSubscription: subscription, }); err != nil { - s.lggr.Errorf("unexpected error updating subscription in the cache: %w", err) + s.lggr.Errorf("unexpected error updating subscription in the db: %w", err) } } } @@ -226,10 +226,10 @@ func (s *onchainSubscriptions) getSubscriptionsCount(ctx context.Context, blockN }) } -func (s *onchainSubscriptions) loadCachedSubscriptions() { +func (s *onchainSubscriptions) loadStoredSubscriptions() { offset := uint(0) for { - csBatch, err := s.orm.GetSubscriptions(offset, s.config.CacheBatchSize) + csBatch, err := s.orm.GetSubscriptions(offset, s.config.StoreBatchSize) if err != nil { break } @@ -244,11 +244,11 @@ func (s *onchainSubscriptions) loadCachedSubscriptions() { Flags: cs.Flags, }) } - s.lggr.Debugw("Loading cached subscriptions", "offset", offset, "batch_length", len(csBatch)) + s.lggr.Debugw("Loading stored subscriptions", "offset", offset, "batch_length", len(csBatch)) - if len(csBatch) != int(s.config.CacheBatchSize) { + if len(csBatch) != int(s.config.StoreBatchSize) { break } - offset += s.config.CacheBatchSize + offset += s.config.StoreBatchSize } } diff --git a/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go b/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go index 94cd1f424e8..be1d2520434 100644 --- a/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go +++ b/core/services/gateway/handlers/functions/subscriptions/subscriptions_test.go @@ -25,7 +25,7 @@ import ( const ( validUser = "0x9ED925d8206a4f88a2f643b28B3035B315753Cd6" invalidUser = "0x6E2dc0F9DB014aE19888F539E59285D2Ea04244C" - cachedUser = "0x3E2dc0F9DB014aE19888F539E59285D2Ea04233G" + storedUser = "0x3E2dc0F9DB014aE19888F539E59285D2Ea04233G" ) func TestSubscriptions_OnePass(t *testing.T) { @@ -51,7 +51,7 @@ func TestSubscriptions_OnePass(t *testing.T) { UpdateRangeSize: 3, } orm := smocks.NewORM(t) - orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.CachedSubscription{}, nil) + orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.StoredSubscription{}, nil) orm.On("UpsertSubscription", mock.Anything).Return(nil) subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -102,7 +102,7 @@ func TestSubscriptions_MultiPass(t *testing.T) { UpdateRangeSize: 3, } orm := smocks.NewORM(t) - orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.CachedSubscription{}, nil) + orm.On("GetSubscriptions", uint(0), uint(100)).Return([]subscriptions.StoredSubscription{}, nil) orm.On("UpsertSubscription", mock.Anything).Return(nil) subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) require.NoError(t, err) @@ -118,7 +118,7 @@ func TestSubscriptions_MultiPass(t *testing.T) { }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) } -func TestSubscriptions_Cached(t *testing.T) { +func TestSubscriptions_Stored(t *testing.T) { getSubscriptionCount := hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000003") getSubscriptionsInRange := hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000109e6e1b12098cc8f3a1e9719a817ec53ab9b35c000000000000000000000000000000000000000000000000000034e23f515cb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f5340f0968ee8b7dfd97e3327a6139273cc2c4fa000000000000000000000000000000000000000000000001158e460913d000000000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bc14b92364c75e20000000000000000000000009ed925d8206a4f88a2f643b28b3035b315753cd60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005439e5881a529f3ccbffc0e82d49f9db3950aefe") @@ -139,22 +139,22 @@ func TestSubscriptions_Cached(t *testing.T) { UpdateFrequencySec: 1, UpdateTimeoutSec: 1, UpdateRangeSize: 3, - CacheBatchSize: 1, + StoreBatchSize: 1, } expectedBalance := big.NewInt(5) orm := smocks.NewORM(t) - orm.On("GetSubscriptions", uint(0), uint(1)).Return([]subscriptions.CachedSubscription{ + orm.On("GetSubscriptions", uint(0), uint(1)).Return([]subscriptions.StoredSubscription{ { SubscriptionID: 1, IFunctionsSubscriptionsSubscription: functions_router.IFunctionsSubscriptionsSubscription{ Balance: expectedBalance, - Owner: common.HexToAddress(cachedUser), + Owner: common.HexToAddress(storedUser), BlockedBalance: big.NewInt(10), }, }, }, nil) - orm.On("GetSubscriptions", uint(1), uint(1)).Return([]subscriptions.CachedSubscription{}, nil) + orm.On("GetSubscriptions", uint(1), uint(1)).Return([]subscriptions.StoredSubscription{}, nil) orm.On("UpsertSubscription", mock.Anything).Return(nil) subscriptions, err := subscriptions.NewOnchainSubscriptions(client, config, orm, logger.TestLogger(t)) @@ -167,7 +167,7 @@ func TestSubscriptions_Cached(t *testing.T) { }) gomega.NewGomegaWithT(t).Eventually(func() bool { - actualBalance, err := subscriptions.GetMaxUserBalance(common.HexToAddress(cachedUser)) + actualBalance, err := subscriptions.GetMaxUserBalance(common.HexToAddress(storedUser)) return err == nil && assert.Equal(t, expectedBalance, actualBalance) }, testutils.WaitTimeout(t), time.Second).Should(gomega.BeTrue()) } diff --git a/core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go b/core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go index 2835fe6c89c..ec506b6a864 100644 --- a/core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go +++ b/core/services/gateway/handlers/functions/subscriptions/user_subscriptions.go @@ -31,8 +31,8 @@ func NewUserSubscriptions() UserSubscriptions { } } -// CachedSubscription is used to populate the user subscription maps from a persistent layer like postgres. -type CachedSubscription struct { +// StoredSubscription is used to populate the user subscription maps from a persistent layer like postgres. +type StoredSubscription struct { SubscriptionID uint64 functions_router.IFunctionsSubscriptionsSubscription } From 6b570419cdfdb1bff3153915cdfb36a486fb91f8 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Fri, 19 Jan 2024 11:40:53 +0100 Subject: [PATCH 19/23] feat: implement GetBlockedSendersInRange and GetBlockedSendersCount in tos contract --- .../gas-snapshots/functions.gas-snapshot | 154 +++++++++--------- .../accessControl/TermsOfServiceAllowList.sol | 36 +++- .../interfaces/ITermsOfServiceAllowList.sol | 26 ++- .../FunctionsTermsOfServiceAllowList.t.sol | 88 ++++++++++ .../functions_allow_list.go | 52 +++++- ...rapper-dependency-versions-do-not-edit.txt | 2 +- 6 files changed, 271 insertions(+), 87 deletions(-) diff --git a/contracts/gas-snapshots/functions.gas-snapshot b/contracts/gas-snapshots/functions.gas-snapshot index a7ddb4cf6c5..39efc0d10ea 100644 --- a/contracts/gas-snapshots/functions.gas-snapshot +++ b/contracts/gas-snapshots/functions.gas-snapshot @@ -1,12 +1,12 @@ -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14749683) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14749661) -ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14749677) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14761097) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14761074) -ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14761046) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14760997) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14760986) -ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14761030) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumGoerli() (gas: 14805978) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumMainnet() (gas: 14805956) +ChainSpecificUtil__getCurrentTxL1GasFees_Arbitrum:test__getCurrentTxL1GasFees_SuccessWhenArbitrumSepolia() (gas: 14805972) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseGoerli() (gas: 14817392) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseMainnet() (gas: 14817369) +ChainSpecificUtil__getCurrentTxL1GasFees_Base:test__getCurrentTxL1GasFees_SuccessWhenBaseSepolia() (gas: 14817341) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismGoerli() (gas: 14817292) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismMainnet() (gas: 14817281) +ChainSpecificUtil__getCurrentTxL1GasFees_Optimism:test__getCurrentTxL1GasFees_SuccessWhenOptimismSepolia() (gas: 14817325) FunctionsBilling_Constructor:test_Constructor_Success() (gas: 14812) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_RevertIfNotRouter() (gas: 13282) FunctionsBilling_DeleteCommitment:test_DeleteCommitment_Success() (gas: 15897) @@ -28,7 +28,7 @@ FunctionsBilling_UpdateConfig:test_UpdateConfig_Success() (gas: 38251) FunctionsBilling__DisperseFeePool:test__DisperseFeePool_RevertIfNotSet() (gas: 8810) FunctionsBilling__FulfillAndBill:test__FulfillAndBill_RevertIfInvalidCommitment() (gas: 13302) FunctionsBilling__FulfillAndBill:test__FulfillAndBill_Success() (gas: 180763) -FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398356) +FunctionsBilling__StartBilling:test__FulfillAndBill_HasUniqueGlobalRequestId() (gas: 398400) FunctionsClient_Constructor:test_Constructor_Success() (gas: 7573) FunctionsClient_FulfillRequest:test_FulfillRequest_MaximumGas() (gas: 497786) FunctionsClient_FulfillRequest:test_FulfillRequest_MinimumGas() (gas: 198990) @@ -61,7 +61,7 @@ FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 280 FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 151496) FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 321059) FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 334680) -FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2509984) +FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2510006) FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 540441) FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 17983) FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12904) @@ -82,17 +82,17 @@ FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfLengt FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotNewContract() (gas: 19048) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_RevertIfNotOwner() (gas: 23392) FunctionsRouter_ProposeContractsUpdate:test_ProposeContractsUpdate_Success() (gas: 118479) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59369) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfConsumerNotAllowed() (gas: 59391) FunctionsRouter_SendRequest:test_SendRequest_RevertIfDuplicateRequestId() (gas: 193436) FunctionsRouter_SendRequest:test_SendRequest_RevertIfEmptyData() (gas: 29426) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57925) -FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 186976) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfIncorrectDonId() (gas: 57904) +FunctionsRouter_SendRequest:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 187020) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 50947) FunctionsRouter_SendRequest:test_SendRequest_RevertIfInvalidDonId() (gas: 25082) FunctionsRouter_SendRequest:test_SendRequest_RevertIfNoSubscription() (gas: 29132) FunctionsRouter_SendRequest:test_SendRequest_RevertIfPaused() (gas: 34291) FunctionsRouter_SendRequest:test_SendRequest_Success() (gas: 286243) -FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65865) +FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfConsumerNotAllowed() (gas: 65887) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfEmptyData() (gas: 36012) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfIncorrectDonId() (gas: 29896) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalidCallbackGasLimit() (gas: 57533) @@ -100,7 +100,7 @@ FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfInvalid FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfNoSubscription() (gas: 35717) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_RevertIfPaused() (gas: 40810) FunctionsRouter_SendRequestToProposed:test_SendRequestToProposed_Success() (gas: 292812) -FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193468) +FunctionsRouter_SendRequestToProposed:test_SendRequest_RevertIfInsufficientSubscriptionBalance() (gas: 193512) FunctionsRouter_SetAllowListId:test_SetAllowListId_Success() (gas: 30688) FunctionsRouter_SetAllowListId:test_UpdateConfig_RevertIfNotOwner() (gas: 13403) FunctionsRouter_Unpause:test_Unpause_RevertIfNotOwner() (gas: 13293) @@ -109,30 +109,30 @@ FunctionsRouter_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 24437) FunctionsRouter_UpdateConfig:test_UpdateConfig_Success() (gas: 60676) FunctionsRouter_UpdateContracts:test_UpdateContracts_RevertIfNotOwner() (gas: 13336) FunctionsRouter_UpdateContracts:test_UpdateContracts_Success() (gas: 38732) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60370) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61009) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 94743) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62737) -FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 215241) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 137959) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164903) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 60414) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfPaused() (gas: 61031) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderBecomesBlocked() (gas: 139404) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_RevertIfSenderIsNotNewOwner() (gas: 62781) +FunctionsSubscriptions_AcceptSubscriptionOwnerTransfer:test_AcceptSubscriptionOwnerTransfer_Success() (gas: 215285) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumers() (gas: 138025) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfMaximumConsumersAfterConfigUpdate() (gas: 164969) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNoSubscription() (gas: 12946) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 57831) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87228) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotAllowedSender() (gas: 102448) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfNotSubscriptionOwner() (gas: 87199) FunctionsSubscriptions_AddConsumer:test_AddConsumer_RevertIfPaused() (gas: 18094) -FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95502) +FunctionsSubscriptions_AddConsumer:test_AddConsumer_Success() (gas: 95524) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubscription() (gas: 15041) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57907) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89338) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 102524) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89309) FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20148) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194347) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114524) -FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125849) -FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 74995) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 194369) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 114541) +FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 125867) +FunctionsSubscriptions_CancelSubscription_ReceiveDeposit:test_CancelSubscription_SuccessRecieveDeposit() (gas: 75017) FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7654) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28682) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28704) FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17994) -FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 351792) +FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_Success() (gas: 351858) FunctionsSubscriptions_GetConsumer:test_GetConsumer_Success() (gas: 16226) FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessInvalidSubscription() (gas: 13101) FunctionsSubscriptions_GetFlags:test_GetFlags_SuccessValidSubscription() (gas: 40903) @@ -168,23 +168,23 @@ FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() ( FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 14981) FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 176494) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27633) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57753) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27655) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57797) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15001) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 75153) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotAllowedSender() (gas: 119770) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNotSubscriptionOwner() (gas: 17960) FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfPaused() (gas: 20128) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68218) -FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 82793) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_Success() (gas: 68240) +FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_SuccessChangeProposedOwner() (gas: 82837) FunctionsSubscriptions_RecoverFunds:test_OwnerCancelSubscription_RevertIfNotOwner() (gas: 15554) FunctionsSubscriptions_RecoverFunds:test_RecoverFunds_Success() (gas: 41111) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30282) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfInvalidConsumer() (gas: 30304) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription() (gas: 15019) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57822) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87274) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 102439) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87245) FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18049) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191880) -FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42001) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 191902) +FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 42023) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12891) FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15684) FunctionsSubscriptions_SetFlags:test_SetFlags_Success() (gas: 35594) @@ -192,38 +192,44 @@ FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfPaused() (ga FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertIfTimeoutNotExceeded() (gas: 25261) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_RevertInvalidRequest() (gas: 28242) FunctionsSubscriptions_TimeoutRequests:test_TimeoutRequests_Success() (gas: 57754) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26412) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfNotAllowedSender() (gas: 26434) FunctionsSubscriptions_createSubscription:test_CreateSubscription_RevertIfPaused() (gas: 15759) -FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152642) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94827) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25888) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44424) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23648) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866581) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26054) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946635) -FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 103503) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469) -FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 51848) -FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12209) -FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19265) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12128365) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16560) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13279) -FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20426) +FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas: 152708) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:testAcceptTermsOfService_InvalidSigner_vuln() (gas: 94864) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25859) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 88990) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23619) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866552) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26025) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946628) +FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 103533) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15491) +FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 96662) +FunctionsTermsOfServiceAllowList_Constructor:test_Constructor_Success() (gas: 12253) +FunctionsTermsOfServiceAllowList_GetAllAllowedSenders:test_GetAllAllowedSenders_Success() (gas: 19199) +FunctionsTermsOfServiceAllowList_GetAllowedSendersCount:test_GetAllowedSendersCount_Success() (gas: 12995) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12184656) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16571) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13301) +FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange:test_GetAllowedSendersInRange_Success() (gas: 20448) +FunctionsTermsOfServiceAllowList_GetBlockedSendersCount:test_GetBlockedSendersCount_Success() (gas: 12931) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() (gas: 12184660) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() (gas: 16549) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() (gas: 13367) +FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange:test_GetBlockedSendersInRange_Success() (gas: 18493) FunctionsTermsOfServiceAllowList_GetConfig:test_GetConfig_Success() (gas: 15751) -FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11637) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15947) -FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23452) -FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15332) -FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 41935) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13480) -FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95205) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13727) -FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22051) -Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84687) -Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79109) -Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73397) +FunctionsTermsOfServiceAllowList_GetMessage:test_GetMessage_Success() (gas: 11593) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_FalseWhenEnabled() (gas: 15969) +FunctionsTermsOfServiceAllowList_HasAccess:test_HasAccess_TrueWhenDisabled() (gas: 23496) +FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessFalse() (gas: 15445) +FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTrue() (gas: 86643) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13502) +FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 96216) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13749) +FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22073) +Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84702) +Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79131) +Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73419) Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38546) Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 979631) Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 157578) \ No newline at end of file diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol index ba31cd287a5..3d93a3fef04 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/TermsOfServiceAllowList.sol @@ -20,7 +20,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, string public constant override typeAndVersion = "Functions Terms of Service Allow List v1.1.0"; EnumerableSet.AddressSet private s_allowedSenders; - mapping(address => bool) private s_blockedSenders; + EnumerableSet.AddressSet private s_blockedSenders; event AddedAccess(address user); event BlockedAccess(address user); @@ -71,7 +71,7 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, /// @inheritdoc ITermsOfServiceAllowList function acceptTermsOfService(address acceptor, address recipient, bytes32 r, bytes32 s, uint8 v) external override { - if (s_blockedSenders[recipient]) { + if (s_blockedSenders.contains(recipient)) { revert RecipientIsBlocked(); } @@ -145,19 +145,45 @@ contract TermsOfServiceAllowList is ITermsOfServiceAllowList, IAccessController, if (!s_config.enabled) { return false; } - return s_blockedSenders[sender]; + return s_blockedSenders.contains(sender); } /// @inheritdoc ITermsOfServiceAllowList function blockSender(address sender) external override onlyOwner { s_allowedSenders.remove(sender); - s_blockedSenders[sender] = true; + s_blockedSenders.add(sender); emit BlockedAccess(sender); } /// @inheritdoc ITermsOfServiceAllowList function unblockSender(address sender) external override onlyOwner { - s_blockedSenders[sender] = false; + s_blockedSenders.remove(sender); emit UnblockedAccess(sender); } + + /// @inheritdoc ITermsOfServiceAllowList + function getBlockedSendersCount() external view override returns (uint64) { + return uint64(s_blockedSenders.length()); + } + + /// @inheritdoc ITermsOfServiceAllowList + function getBlockedSendersInRange( + uint64 blockedSenderIdxStart, + uint64 blockedSenderIdxEnd + ) external view override returns (address[] memory blockedSenders) { + if ( + blockedSenderIdxStart > blockedSenderIdxEnd || + blockedSenderIdxEnd >= s_blockedSenders.length() || + s_blockedSenders.length() == 0 + ) { + revert InvalidCalldata(); + } + + blockedSenders = new address[]((blockedSenderIdxEnd - blockedSenderIdxStart) + 1); + for (uint256 i = 0; i <= blockedSenderIdxEnd - blockedSenderIdxStart; ++i) { + blockedSenders[i] = s_blockedSenders.at(uint256(blockedSenderIdxStart + i)); + } + + return blockedSenders; + } } diff --git a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol index 51c0ca34533..65db9c42b69 100644 --- a/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol +++ b/contracts/src/v0.8/functions/dev/v1_X/accessControl/interfaces/ITermsOfServiceAllowList.sol @@ -30,12 +30,12 @@ interface ITermsOfServiceAllowList { /// @dev WARNING: getAllowedSendersInRange uses EnumerableSet .length() and .at() methods to iterate over the list /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. /// Evaluate if eventual consistency will satisfy your usecase before using it. - /// @param allowedSenderIdStart - the ID of the allowed sender to start the range at - /// @param allowedSenderIdEnd - the ID of the allowed sender to end the range at - /// @return allowedSenders - all allowed addresses + /// @param allowedSenderIdxStart - index of the allowed sender to start the range at + /// @param allowedSenderIdxEnd - index of the allowed sender to end the range at + /// @return allowedSenders - allowed addresses in the range provided function getAllowedSendersInRange( - uint64 allowedSenderIdStart, - uint64 allowedSenderIdEnd + uint64 allowedSenderIdxStart, + uint64 allowedSenderIdxEnd ) external view returns (address[] memory allowedSenders); /// @notice Allows access to the sender based on acceptance of the Terms of Service @@ -53,6 +53,22 @@ interface ITermsOfServiceAllowList { /// @notice Re-allows a previously blocked sender to accept the Terms of Service /// @param sender - Address of the sender to unblock function unblockSender(address sender) external; + + /// @notice Get details about the total number of blocked senders + /// @return count - total number of blocked senders in the system + function getBlockedSendersCount() external view returns (uint64); + + /// @notice Retrieve a list of blocked senders using an inclusive range + /// @dev WARNING: getBlockedSendersInRange uses EnumerableSet .length() and .at() methods to iterate over the list + /// without the need for an extra mapping. These method can not guarantee the ordering when new elements are added. + /// Evaluate if eventual consistency will satisfy your usecase before using it. + /// @param blockedSenderIdxStart - index of the blocked sender to start the range at + /// @param blockedSenderIdxEnd - index of the blocked sender to end the range at + /// @return blockedSenders - blocked addresses in the range provided + function getBlockedSendersInRange( + uint64 blockedSenderIdxStart, + uint64 blockedSenderIdxEnd + ) external view returns (address[] memory blockedSenders); } // ================================================================ diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol index b9b2cb8efc1..8a78c03943c 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol @@ -247,6 +247,19 @@ contract FunctionsTermsOfServiceAllowList_GetAllAllowedSenders is FunctionsOwner } } +/// @notice #getAllowedSendersCount +contract FunctionsTermsOfServiceAllowList_GetAllowedSendersCount is FunctionsOwnerAcceptTermsOfServiceSetup { + function test_GetAllowedSendersCount_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint96 allowedSendersCount = s_termsOfServiceAllowList.getAllowedSendersCount(); + // One allowed sender was made during setup + assertEq(allowedSendersCount, 1); + } +} + /// @notice #getAllowedSendersInRange contract FunctionsTermsOfServiceAllowList_GetAllowedSendersInRange is FunctionsOwnerAcceptTermsOfServiceSetup { function test_GetAllowedSendersInRange_Success() public { @@ -423,3 +436,78 @@ contract FunctionsTermsOfServiceAllowList_UnblockSender is FunctionsRoutesSetup s_termsOfServiceAllowList.acceptTermsOfService(STRANGER_ADDRESS, STRANGER_ADDRESS, r, s, v); } } + +/// @notice #getBlockedSendersCount +contract FunctionsTermsOfServiceAllowList_GetBlockedSendersCount is FunctionsRoutesSetup { + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); + } + + function test_GetBlockedSendersCount_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint96 blockedSendersCount = s_termsOfServiceAllowList.getBlockedSendersCount(); + // One blocked sender was made during setup + assertEq(blockedSendersCount, 1); + } +} + +/// @notice #getBlockedSendersInRange +contract FunctionsTermsOfServiceAllowList_GetBlockedSendersInRange is FunctionsRoutesSetup { + function setUp() public virtual override { + FunctionsRoutesSetup.setUp(); + + s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); + } + + function test_GetBlockedSendersInRange_Success() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + address[] memory expectedBlockedSenders = new address[](1); + expectedBlockedSenders[0] = STRANGER_ADDRESS; + + assertEq(s_termsOfServiceAllowList.getBlockedSendersInRange(0, 0), expectedBlockedSenders); + } + + function test_GetBlockedSendersInRange_RevertIfAllowedSendersIsEmpty() public { + // setup a new empty s_termsOfServiceBlockList + FunctionsRoutesSetup.setUp(); + + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint64 BlockedSendersCount = s_termsOfServiceAllowList.getBlockedSendersCount(); + uint64 expected = 0; + assertEq(BlockedSendersCount, expected); + + vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); + s_termsOfServiceAllowList.getBlockedSendersInRange(0, 0); + } + + function test_GetBlockedSendersInRange_RevertIfStartIsAfterEnd() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); + + s_termsOfServiceAllowList.getBlockedSendersInRange(1, 0); + } + + function test_GetBlockedSendersInRange_RevertIfEndIsAfterLastAllowedSender() public { + // Send as stranger + vm.stopPrank(); + vm.startPrank(STRANGER_ADDRESS); + + uint64 BlockedSendersCount = s_termsOfServiceAllowList.getBlockedSendersCount(); + vm.expectRevert(TermsOfServiceAllowList.InvalidCalldata.selector); + s_termsOfServiceAllowList.getBlockedSendersInRange(1, BlockedSendersCount + 1); + } +} diff --git a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go index 9d2a2c88621..ff15cc75d41 100644 --- a/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go +++ b/core/gethwrappers/functions/generated/functions_allow_list/functions_allow_list.go @@ -36,8 +36,8 @@ type TermsOfServiceAllowListConfig struct { } var TermsOfServiceAllowListMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b506040516200161b3803806200161b833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160058054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b61132180620002fa6000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806382184c7b11610097578063a5e1d61d11610066578063a5e1d61d1461025a578063c3f909d41461026d578063cc7ebf49146102cc578063f2fde38b146102ed57600080fd5b806382184c7b1461019357806389f9a2c4146101a65780638da5cb5b146101b9578063a39b06e3146101e157600080fd5b806347663acb116100d357806347663acb1461014d5780636b14daf81461016057806379ba509714610183578063817ef62e1461018b57600080fd5b80630a8c9c24146100fa578063181f5a77146101235780633908c4d414610138575b600080fd5b61010d610108366004610ebd565b610300565b60405161011a9190610ef0565b60405180910390f35b61012b61046e565b60405161011a9190610f4a565b61014b610146366004610fda565b61048a565b005b61014b61015b36600461103b565b610753565b61017361016e366004611056565b6107de565b604051901515815260200161011a565b61014b610808565b61010d61090a565b61014b6101a136600461103b565b61091b565b61014b6101b4366004611108565b6109ae565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61024c6101ef366004611191565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161011a565b61017361026836600461103b565b610a69565b60408051808201825260008082526020918201528151808301835260055460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161011a565b6102d4610aaa565b60405167ffffffffffffffff909116815260200161011a565b61014b6102fb36600461103b565b610ab6565b60608167ffffffffffffffff168367ffffffffffffffff16118061033757506103296002610aca565b8267ffffffffffffffff1610155b8061034957506103476002610aca565b155b15610380576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61038a83836111ea565b61039590600161120b565b67ffffffffffffffff1667ffffffffffffffff8111156103b7576103b76110d9565b6040519080825280602002602001820160405280156103e0578160200160208202803683370190505b50905060005b6103f084846111ea565b67ffffffffffffffff1681116104665761041f6104178267ffffffffffffffff871661122c565b600290610ad4565b8282815181106104315761043161123f565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261045f8161126e565b90506103e6565b505b92915050565b6040518060600160405280602c81526020016112e9602c913981565b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602052604090205460ff16156104ea576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206005546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa15801561061e573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614610675576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff86161415806106ba57503373ffffffffffffffffffffffffffffffffffffffff8716148015906106ba5750333b155b156106f1576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106fc600286610ae0565b1561074b5760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b61075b610b02565b73ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905590519182527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b91015b60405180910390a150565b60055460009060ff166107f357506001610801565b6107fe600285610b85565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461088e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606109166002610bb4565b905090565b610923610b02565b61092e600282610bc1565b5073ffffffffffffffffffffffffffffffffffffffff811660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905590519182527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e191016107d3565b6109b6610b02565b805160058054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a91016107d3565b60055460009060ff16610a7e57506000919050565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526004602052604090205460ff1690565b60006109166002610aca565b610abe610b02565b610ac781610be3565b50565b6000610468825490565b60006108018383610cd8565b60006108018373ffffffffffffffffffffffffffffffffffffffff8416610d02565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610885565b565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610801565b6060600061080183610d51565b60006108018373ffffffffffffffffffffffffffffffffffffffff8416610dad565b3373ffffffffffffffffffffffffffffffffffffffff821603610c62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610885565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610cef57610cef61123f565b9060005260206000200154905092915050565b6000818152600183016020526040812054610d4957508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610468565b506000610468565b606081600001805480602002602001604051908101604052809291908181526020018280548015610da157602002820191906000526020600020905b815481526020019060010190808311610d8d575b50505050509050919050565b60008181526001830160205260408120548015610e96576000610dd16001836112a6565b8554909150600090610de5906001906112a6565b9050818114610e4a576000866000018281548110610e0557610e0561123f565b9060005260206000200154905080876000018481548110610e2857610e2861123f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e5b57610e5b6112b9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610468565b6000915050610468565b803567ffffffffffffffff81168114610eb857600080fd5b919050565b60008060408385031215610ed057600080fd5b610ed983610ea0565b9150610ee760208401610ea0565b90509250929050565b6020808252825182820181905260009190848201906040850190845b81811015610f3e57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f0c565b50909695505050505050565b600060208083528351808285015260005b81811015610f7757858101830151858201604001528201610f5b565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610eb857600080fd5b600080600080600060a08688031215610ff257600080fd5b610ffb86610fb6565b945061100960208701610fb6565b93506040860135925060608601359150608086013560ff8116811461102d57600080fd5b809150509295509295909350565b60006020828403121561104d57600080fd5b61080182610fb6565b60008060006040848603121561106b57600080fd5b61107484610fb6565b9250602084013567ffffffffffffffff8082111561109157600080fd5b818601915086601f8301126110a557600080fd5b8135818111156110b457600080fd5b8760208285010111156110c657600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561111a57600080fd5b6040516040810181811067ffffffffffffffff82111715611164577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461117757600080fd5b815261118560208401610fb6565b60208201529392505050565b600080604083850312156111a457600080fd5b6111ad83610fb6565b9150610ee760208401610fb6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115610466576104666111bb565b67ffffffffffffffff818116838216019080821115610466576104666111bb565b80820180821115610468576104686111bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361129f5761129f6111bb565b5060010190565b81810381811115610468576104686111bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidUsage\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RecipientIsBlocked\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AddedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"BlockedAccess\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"UnblockedAccess\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"}],\"name\":\"acceptTermsOfService\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"blockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAllowedSenders\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"allowedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getAllowedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"allowedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockedSendersCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxStart\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"blockedSenderIdxEnd\",\"type\":\"uint64\"}],\"name\":\"getBlockedSendersInRange\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"blockedSenders\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"acceptor\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"getMessage\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"hasAccess\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"isBlockedSender\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"unblockSender\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"signerPublicKey\",\"type\":\"address\"}],\"internalType\":\"structTermsOfServiceAllowListConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b506040516200173438038062001734833981016040819052620000349162000269565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018460201b60201c565b50620002ea565b336001600160a01b03821603620001335760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018e6200020b565b805160068054602080850180516001600160a81b0319909316941515610100600160a81b03198116959095176101006001600160a01b039485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910160405180910390a150565b6000546001600160a01b03163314620002675760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b6000604082840312156200027c57600080fd5b604080519081016001600160401b0381118282101715620002ad57634e487b7160e01b600052604160045260246000fd5b60405282518015158114620002c157600080fd5b815260208301516001600160a01b0381168114620002de57600080fd5b60208201529392505050565b61143a80620002fa6000396000f3fe608060405234801561001057600080fd5b506004361061011b5760003560e01c8063817ef62e116100b2578063a39b06e311610081578063c3f909d411610066578063c3f909d4146102c3578063cc7ebf4914610322578063f2fde38b1461032a57600080fd5b8063a39b06e314610237578063a5e1d61d146102b057600080fd5b8063817ef62e146101e157806382184c7b146101e957806389f9a2c4146101fc5780638da5cb5b1461020f57600080fd5b80633908c4d4116100ee5780633908c4d41461018e57806347663acb146101a35780636b14daf8146101b657806379ba5097146101d957600080fd5b806301a05958146101205780630a8c9c2414610146578063181f5a771461016657806320229a861461017b575b600080fd5b61012861033d565b60405167ffffffffffffffff90911681526020015b60405180910390f35b610159610154366004610fd6565b61034e565b60405161013d9190611009565b61016e6104bc565b60405161013d9190611063565b610159610189366004610fd6565b6104d8565b6101a161019c3660046110f3565b61063e565b005b6101a16101b1366004611154565b6108e9565b6101c96101c436600461116f565b61094a565b604051901515815260200161013d565b6101a1610974565b610159610a76565b6101a16101f7366004611154565b610a82565b6101a161020a366004611221565b610ae8565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161013d565b6102a26102453660046112aa565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60405190815260200161013d565b6101c96102be366004611154565b610ba3565b60408051808201825260008082526020918201528151808301835260065460ff8116151580835273ffffffffffffffffffffffffffffffffffffffff61010090920482169284019283528451908152915116918101919091520161013d565b610128610bc3565b6101a1610338366004611154565b610bcf565b60006103496004610be3565b905090565b60608167ffffffffffffffff168367ffffffffffffffff16118061038557506103776002610be3565b8267ffffffffffffffff1610155b8061039757506103956002610be3565b155b156103ce576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103d88383611303565b6103e3906001611324565b67ffffffffffffffff1667ffffffffffffffff811115610405576104056111f2565b60405190808252806020026020018201604052801561042e578160200160208202803683370190505b50905060005b61043e8484611303565b67ffffffffffffffff1681116104b45761046d6104658267ffffffffffffffff8716611345565b600290610bed565b82828151811061047f5761047f611358565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101526104ad81611387565b9050610434565b505b92915050565b6040518060600160405280602c8152602001611402602c913981565b60608167ffffffffffffffff168367ffffffffffffffff16118061050f57506105016004610be3565b8267ffffffffffffffff1610155b80610521575061051f6004610be3565b155b15610558576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105628383611303565b61056d906001611324565b67ffffffffffffffff1667ffffffffffffffff81111561058f5761058f6111f2565b6040519080825280602002602001820160405280156105b8578160200160208202803683370190505b50905060005b6105c88484611303565b67ffffffffffffffff1681116104b4576105f76105ef8267ffffffffffffffff8716611345565b600490610bed565b82828151811061060957610609611358565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015261063781611387565b90506105be565b610649600485610bf9565b15610680576040517f62b7a34d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051606087811b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009081166020808501919091529188901b16603483015282516028818403018152604890920190925280519101206000906040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c810191909152605c01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815282825280516020918201206006546000855291840180845281905260ff8616928401929092526060830187905260808301869052909250610100900473ffffffffffffffffffffffffffffffffffffffff169060019060a0016020604051602081039080840390855afa1580156107b4573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff161461080b576040517f8baa579f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff861614158061085057503373ffffffffffffffffffffffffffffffffffffffff8716148015906108505750333b155b15610887576040517f381cfcbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610892600286610c28565b156108e15760405173ffffffffffffffffffffffffffffffffffffffff861681527f87286ad1f399c8e82bf0c4ef4fcdc570ea2e1e92176e5c848b6413545b885db49060200160405180910390a15b505050505050565b6108f1610c4a565b6108fc600482610ccd565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f28bbd0761309a99e8fb5e5d02ada0b7b2db2e5357531ff5dbfc205c3f5b6592b906020015b60405180910390a150565b60065460009060ff1661095f5750600161096d565b61096a600285610bf9565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109fa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60606103496002610cef565b610a8a610c4a565b610a95600282610ccd565b50610aa1600482610c28565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527f337cd0f3f594112b6d830afb510072d3b08556b446514f73b8109162fd1151e19060200161093f565b610af0610c4a565b805160068054602080850180517fffffffffffffffffffffff0000000000000000000000000000000000000000009093169415157fffffffffffffffffffffff0000000000000000000000000000000000000000ff81169590951761010073ffffffffffffffffffffffffffffffffffffffff9485160217909355604080519485529251909116908301527f0d22b8a99f411b3dd338c961284f608489ca0dab9cdad17366a343c361bcf80a910161093f565b60065460009060ff16610bb857506000919050565b6104b6600483610bf9565b60006103496002610be3565b610bd7610c4a565b610be081610cfc565b50565b60006104b6825490565b600061096d8383610df1565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600183016020526040812054151561096d565b600061096d8373ffffffffffffffffffffffffffffffffffffffff8416610e1b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ccb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016109f1565b565b600061096d8373ffffffffffffffffffffffffffffffffffffffff8416610e6a565b6060600061096d83610f5d565b3373ffffffffffffffffffffffffffffffffffffffff821603610d7b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016109f1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000826000018281548110610e0857610e08611358565b9060005260206000200154905092915050565b6000818152600183016020526040812054610e62575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104b6565b5060006104b6565b60008181526001830160205260408120548015610f53576000610e8e6001836113bf565b8554909150600090610ea2906001906113bf565b9050818114610f07576000866000018281548110610ec257610ec2611358565b9060005260206000200154905080876000018481548110610ee557610ee5611358565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610f1857610f186113d2565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104b6565b60009150506104b6565b606081600001805480602002602001604051908101604052809291908181526020018280548015610fad57602002820191906000526020600020905b815481526020019060010190808311610f99575b50505050509050919050565b803567ffffffffffffffff81168114610fd157600080fd5b919050565b60008060408385031215610fe957600080fd5b610ff283610fb9565b915061100060208401610fb9565b90509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561105757835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101611025565b50909695505050505050565b600060208083528351808285015260005b8181101561109057858101830151858201604001528201611074565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610fd157600080fd5b600080600080600060a0868803121561110b57600080fd5b611114866110cf565b9450611122602087016110cf565b93506040860135925060608601359150608086013560ff8116811461114657600080fd5b809150509295509295909350565b60006020828403121561116657600080fd5b61096d826110cf565b60008060006040848603121561118457600080fd5b61118d846110cf565b9250602084013567ffffffffffffffff808211156111aa57600080fd5b818601915086601f8301126111be57600080fd5b8135818111156111cd57600080fd5b8760208285010111156111df57600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006040828403121561123357600080fd5b6040516040810181811067ffffffffffffffff8211171561127d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040528235801515811461129057600080fd5b815261129e602084016110cf565b60208201529392505050565b600080604083850312156112bd57600080fd5b6112c6836110cf565b9150611000602084016110cf565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff8281168282160390808211156104b4576104b46112d4565b67ffffffffffffffff8181168382160190808211156104b4576104b46112d4565b808201808211156104b6576104b66112d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036113b8576113b86112d4565b5060010190565b818103818111156104b6576104b66112d4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfe46756e6374696f6e73205465726d73206f66205365727669636520416c6c6f77204c6973742076312e312e30a164736f6c6343000813000a", } var TermsOfServiceAllowListABI = TermsOfServiceAllowListMetaData.ABI @@ -242,6 +242,50 @@ func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetAllowed return _TermsOfServiceAllowList.Contract.GetAllowedSendersInRange(&_TermsOfServiceAllowList.CallOpts, allowedSenderIdxStart, allowedSenderIdxEnd) } +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetBlockedSendersCount(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getBlockedSendersCount") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetBlockedSendersCount() (uint64, error) { + return _TermsOfServiceAllowList.Contract.GetBlockedSendersCount(&_TermsOfServiceAllowList.CallOpts) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetBlockedSendersCount() (uint64, error) { + return _TermsOfServiceAllowList.Contract.GetBlockedSendersCount(&_TermsOfServiceAllowList.CallOpts) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetBlockedSendersInRange(opts *bind.CallOpts, blockedSenderIdxStart uint64, blockedSenderIdxEnd uint64) ([]common.Address, error) { + var out []interface{} + err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getBlockedSendersInRange", blockedSenderIdxStart, blockedSenderIdxEnd) + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListSession) GetBlockedSendersInRange(blockedSenderIdxStart uint64, blockedSenderIdxEnd uint64) ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetBlockedSendersInRange(&_TermsOfServiceAllowList.CallOpts, blockedSenderIdxStart, blockedSenderIdxEnd) +} + +func (_TermsOfServiceAllowList *TermsOfServiceAllowListCallerSession) GetBlockedSendersInRange(blockedSenderIdxStart uint64, blockedSenderIdxEnd uint64) ([]common.Address, error) { + return _TermsOfServiceAllowList.Contract.GetBlockedSendersInRange(&_TermsOfServiceAllowList.CallOpts, blockedSenderIdxStart, blockedSenderIdxEnd) +} + func (_TermsOfServiceAllowList *TermsOfServiceAllowListCaller) GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) { var out []interface{} err := _TermsOfServiceAllowList.contract.Call(opts, &out, "getConfig") @@ -1241,6 +1285,10 @@ type TermsOfServiceAllowListInterface interface { GetAllowedSendersInRange(opts *bind.CallOpts, allowedSenderIdxStart uint64, allowedSenderIdxEnd uint64) ([]common.Address, error) + GetBlockedSendersCount(opts *bind.CallOpts) (uint64, error) + + GetBlockedSendersInRange(opts *bind.CallOpts, blockedSenderIdxStart uint64, blockedSenderIdxEnd uint64) ([]common.Address, error) + GetConfig(opts *bind.CallOpts) (TermsOfServiceAllowListConfig, error) GetMessage(opts *bind.CallOpts, acceptor common.Address, recipient common.Address) ([32]byte, error) diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 7fba72d7758..16bb718e7c1 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,6 +1,6 @@ GETH_VERSION: 1.13.8 functions: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsRequest.bin 3c972870b0afeb6d73a29ebb182f24956a2cebb127b21c4f867d1ecf19a762db -functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 685b10a36b86a82eff858ba45d71f7bb5ea168fea0e5da3c7c5c2d17dfe72baa +functions_allow_list: ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.abi ../../../contracts/solc/v0.8.19/functions/v1_X/TermsOfServiceAllowList.bin 586696a0cacc0e5112bdd6c99535748a3fbf08c9319360aee868831d38a96d7b functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/v0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/v1_X/FunctionsClientExample.bin abf32e69f268f40e8530eb8d8e96bf310b798a4c0049a58022d9d2fb527b601b From f34208d6747a6cd9842e60dd0f2d2d601393f8a4 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Fri, 19 Jan 2024 15:16:39 +0100 Subject: [PATCH 20/23] feat: implement sync of blocked senders with allowed --- .../FunctionsTermsOfServiceAllowList.t.sol | 2 +- .../handlers/functions/allowlist/allowlist.go | 107 +++++++++++++----- .../functions/allowlist/allowlist_test.go | 1 + .../handlers/functions/allowlist/mocks/orm.go | 25 ++++ .../handlers/functions/allowlist/orm.go | 32 ++++++ .../handlers/functions/allowlist/orm_test.go | 51 +++++++++ 6 files changed, 191 insertions(+), 27 deletions(-) diff --git a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol index 8a78c03943c..e121f7b881d 100644 --- a/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol +++ b/contracts/src/v0.8/functions/tests/v1_X/FunctionsTermsOfServiceAllowList.t.sol @@ -444,7 +444,7 @@ contract FunctionsTermsOfServiceAllowList_GetBlockedSendersCount is FunctionsRou s_termsOfServiceAllowList.blockSender(STRANGER_ADDRESS); } - + function test_GetBlockedSendersCount_Success() public { // Send as stranger vm.stopPrank(); diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go index 51737fa0228..04851b985f2 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -204,8 +204,8 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b if err != nil { return errors.Wrap(err, "unexpected error during functions_allow_list.NewTermsOfServiceAllowList") } - allowedSenderList := make([]common.Address, 0) + var allowedSenderList []common.Address if !a.config.StoreAllowedSendersEnabled { allowedSenderList, err = tosContract.GetAllAllowedSenders(&bind.CallOpts{ Pending: false, @@ -216,43 +216,98 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b return errors.Wrap(err, "error calling GetAllAllowedSenders") } } else { - count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ + err = a.syncStoredAllowedAndBlockedSenders(ctx, tosContract, blockNum) + if err != nil { + return errors.Wrap(err, "failed to sync the stored allowed and blocked senders") + } + + allowedSenderList, err = a.getAllowedSendersInRange(ctx, tosContract, blockNum) + if err != nil { + return errors.Wrap(err, "failed to get allowed senders in rage") + } + } + + a.update(allowedSenderList) + return nil +} + +func (a *onchainAllowlist) getAllowedSendersInRange(ctx context.Context, tosContract *functions_allow_list.TermsOfServiceAllowList, blockNum *big.Int) ([]common.Address, error) { + allowedSenderList := make([]common.Address, 0) + count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }) + if err != nil { + return nil, errors.Wrap(err, "unexpected error during functions_allow_list.GetAllowedSendersCount") + } + + throttleTicker := time.NewTicker(time.Duration(a.config.FetchingDelayInRangeSec) * time.Second) + for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { + <-throttleTicker.C + + idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) + if idxEnd >= count { + idxEnd = count - 1 + } + + allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, Context: ctx, - }) + }, idxStart, idxEnd) if err != nil { - return errors.Wrap(err, "unexpected error during functions_allow_list.GetAllowedSendersCount") + return nil, errors.Wrap(err, "error calling GetAllowedSendersInRange") } - throttleTicker := time.NewTicker(time.Duration(a.config.FetchingDelayInRangeSec) * time.Second) - for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { - <-throttleTicker.C + allowedSenderList = append(allowedSenderList, allowedSendersBatch...) + err = a.orm.CreateAllowedSenders(allowedSendersBatch) + if err != nil { + a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) + } + } + throttleTicker.Stop() - idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) - if idxEnd >= count { - idxEnd = count - 1 - } + return allowedSenderList, nil +} - allowedSendersBatch, err := tosContract.GetAllowedSendersInRange(&bind.CallOpts{ - Pending: false, - BlockNumber: blockNum, - Context: ctx, - }, idxStart, idxEnd) - if err != nil { - return errors.Wrap(err, "error calling GetAllowedSendersInRange") - } +// syncStoredAllowedAndBlockedSenders fetches the list of blocked addresses from the contract in batches +// and removes the addresses from the functions_allowlist table if present +func (a *onchainAllowlist) syncStoredAllowedAndBlockedSenders(ctx context.Context, tosContract *functions_allow_list.TermsOfServiceAllowList, blockNum *big.Int) error { + count, err := tosContract.GetBlockedSendersCount(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }) + if err != nil { + return errors.Wrap(err, "unexpected error during functions_allow_list.GetBlockedSendersCount") + } - allowedSenderList = append(allowedSenderList, allowedSendersBatch...) - err = a.orm.CreateAllowedSenders(allowedSendersBatch) - if err != nil { - a.lggr.Errorf("failed to update stored allowedSenderList: %w", err) - } + throttleTicker := time.NewTicker(time.Duration(a.config.FetchingDelayInRangeSec) * time.Second) + for idxStart := uint64(0); idxStart < count; idxStart += uint64(a.config.OnchainAllowlistBatchSize) { + <-throttleTicker.C + + idxEnd := idxStart + uint64(a.config.OnchainAllowlistBatchSize) + if idxEnd >= count { + idxEnd = count - 1 + } + + blockedSendersBatch, err := tosContract.GetBlockedSendersInRange(&bind.CallOpts{ + Pending: false, + BlockNumber: blockNum, + Context: ctx, + }, idxStart, idxEnd) + if err != nil { + return errors.Wrap(err, "error calling GetAllowedSendersInRange") + } + + err = a.orm.DeleteAllowedSenders(blockedSendersBatch) + if err != nil { + a.lggr.Errorf("failed to delete blocked address from allowed list in storage: %w", err) } - throttleTicker.Stop() } + throttleTicker.Stop() - a.update(allowedSenderList) return nil } diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go index f2596da8591..427fb8a76fb 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -137,6 +137,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { } orm := amocks.NewORM(t) + orm.On("DeleteAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) orm.On("CreateAllowedSenders", []common.Address{common.HexToAddress(addr1), common.HexToAddress(addr2)}).Times(2).Return(nil) allowlist, err := allowlist.NewOnchainAllowlist(client, config, orm, logger.TestLogger(t)) diff --git a/core/services/gateway/handlers/functions/allowlist/mocks/orm.go b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go index b9ef20e3fdf..c2ba27c3a24 100644 --- a/core/services/gateway/handlers/functions/allowlist/mocks/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/mocks/orm.go @@ -39,6 +39,31 @@ func (_m *ORM) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg return r0 } +// DeleteAllowedSenders provides a mock function with given fields: blockedSenders, qopts +func (_m *ORM) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, blockedSenders) + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + if len(ret) == 0 { + panic("no return value specified for DeleteAllowedSenders") + } + + var r0 error + if rf, ok := ret.Get(0).(func([]common.Address, ...pg.QOpt) error); ok { + r0 = rf(blockedSenders, qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // GetAllowedSenders provides a mock function with given fields: offset, limit, qopts func (_m *ORM) GetAllowedSenders(offset uint, limit uint, qopts ...pg.QOpt) ([]common.Address, error) { _va := make([]interface{}, len(qopts)) diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go index 90cc1fa8c30..ed3cad9de1e 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/orm.go @@ -17,6 +17,7 @@ import ( type ORM interface { GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common.Address, error) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error + DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error } type orm struct { @@ -88,3 +89,34 @@ func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.Q return nil } + +func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg.QOpt) error { + var valuesPlaceholder []string + for i := 1; i <= len(blockedSenders); i++ { + valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("$%d", i+1)) + } + + stmt := fmt.Sprintf(` + DELETE FROM %s + WHERE router_contract_address = $1 + AND allowed_address IN (%s);`, tableName, strings.Join(valuesPlaceholder, ", ")) + + args := []interface{}{o.routerContractAddress} + for _, bs := range blockedSenders { + args = append(args, bs) + } + + res, err := o.q.WithOpts(qopts...).Exec(stmt, args...) + if err != nil { + return err + } + + rowsAffected, err := res.RowsAffected() + if err != nil { + return err + } + + o.lggr.Debugf("Successfully removed blocked senders from the allowed list: %s for routerContractAddress: %s. rowsAffected: %d", blockedSenders, o.routerContractAddress, rowsAffected) + + return nil +} diff --git a/core/services/gateway/handlers/functions/allowlist/orm_test.go b/core/services/gateway/handlers/functions/allowlist/orm_test.go index 8b96afc6745..0f63e83cd5f 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm_test.go +++ b/core/services/gateway/handlers/functions/allowlist/orm_test.go @@ -123,6 +123,57 @@ func TestORM_CreateAllowedSenders(t *testing.T) { }) } +func TestORM_DeleteAllowedSenders(t *testing.T) { + t.Parallel() + + t.Run("OK-delete_blocked_sender_from_allowed_list", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + add1 := testutils.NewAddress() + add2 := testutils.NewAddress() + add3 := testutils.NewAddress() + err = orm.CreateAllowedSenders([]common.Address{add1, add2, add3}) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 3, len(results), "incorrect results length") + require.Equal(t, add1, results[0]) + + err = orm.DeleteAllowedSenders([]common.Address{add1, add3}) + require.NoError(t, err) + + results, err = orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 1, len(results), "incorrect results length") + require.Equal(t, add2, results[0]) + }) + + t.Run("OK-delete_non_existing_blocked_sender_from_allowed_list", func(t *testing.T) { + orm, err := setupORM(t) + require.NoError(t, err) + add1 := testutils.NewAddress() + add2 := testutils.NewAddress() + err = orm.CreateAllowedSenders([]common.Address{add1, add2}) + require.NoError(t, err) + + results, err := orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, add1, results[0]) + + add3 := testutils.NewAddress() + err = orm.DeleteAllowedSenders([]common.Address{add3}) + require.NoError(t, err) + + results, err = orm.GetAllowedSenders(0, 10) + require.NoError(t, err) + require.Equal(t, 2, len(results), "incorrect results length") + require.Equal(t, add1, results[0]) + require.Equal(t, add2, results[1]) + }) +} + func Test_NewORM(t *testing.T) { t.Run("OK-create_ORM", func(t *testing.T) { _, err := allowlist.NewORM(pgtest.NewSqlxDB(t), logger.TestLogger(t), pgtest.NewQConfig(true), testutils.NewAddress()) From f9fa8f2ec80c284b29a341c49d5d22d8cda9e5a6 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Mon, 22 Jan 2024 15:18:03 +0100 Subject: [PATCH 21/23] chore: add checks and table constraints --- .../gateway/handlers/functions/allowlist/allowlist.go | 6 +++++- .../handlers/functions/allowlist/allowlist_test.go | 6 +++--- .../gateway/handlers/functions/allowlist/orm.go | 1 + .../gateway/handlers/functions/subscriptions/orm.go | 7 ++++++- .../migrate/migrations/0221_functions_allowlist.sql | 10 +++++++++- 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go index 04851b985f2..5d031a7834b 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -93,10 +93,14 @@ func NewOnchainAllowlist(client evmclient.Client, config OnchainAllowlistConfig, } if config.FetchingDelayInRangeSec == 0 { - lggr.Info("FetchingDelayInRangeSec not specified, using default size: ", defaultOnchainAllowlistBatchSize) + lggr.Info("FetchingDelayInRangeSec not specified, using default delay: ", defaultFetchingDelayInRangeSec) config.FetchingDelayInRangeSec = defaultFetchingDelayInRangeSec } + if config.UpdateFrequencySec != 0 && config.FetchingDelayInRangeSec >= config.UpdateFrequencySec { + return nil, fmt.Errorf("to avoid updates overlapping FetchingDelayInRangeSec:%d should be less than UpdateFrequencySec:%d", config.FetchingDelayInRangeSec, config.UpdateFrequencySec) + } + contractV1, err := functions_router.NewFunctionsRouter(config.ContractAddress, client) if err != nil { return nil, fmt.Errorf("unexpected error during functions_router.NewFunctionsRouter: %s", err) diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go index 427fb8a76fb..e8cbca80b94 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist_test.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist_test.go @@ -94,7 +94,7 @@ func TestAllowlist_UpdatePeriodically(t *testing.T) { ContractAddress: common.Address{}, ContractVersion: 1, BlockConfirmations: 1, - UpdateFrequencySec: 1, + UpdateFrequencySec: 2, UpdateTimeoutSec: 1, } @@ -128,7 +128,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { ContractAddress: common.HexToAddress(addr3), ContractVersion: 1, BlockConfirmations: 1, - UpdateFrequencySec: 1, + UpdateFrequencySec: 2, UpdateTimeoutSec: 1, StoredAllowlistBatchSize: 2, OnchainAllowlistBatchSize: 16, @@ -162,7 +162,7 @@ func TestAllowlist_UpdateFromContract(t *testing.T) { ContractAddress: common.HexToAddress(addr3), ContractVersion: 1, BlockConfirmations: 1, - UpdateFrequencySec: 1, + UpdateFrequencySec: 2, UpdateTimeoutSec: 1, StoredAllowlistBatchSize: 2, OnchainAllowlistBatchSize: 16, diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go index ed3cad9de1e..9ecbbf1feb0 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/orm.go @@ -85,6 +85,7 @@ func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.Q if err != nil { return err } + o.lggr.Debugf("Successfully stored allowed sender: %s for routerContractAddress: %s", allowedSender, o.routerContractAddress) return nil diff --git a/core/services/gateway/handlers/functions/subscriptions/orm.go b/core/services/gateway/handlers/functions/subscriptions/orm.go index 5ef09403708..369291ace54 100644 --- a/core/services/gateway/handlers/functions/subscriptions/orm.go +++ b/core/services/gateway/handlers/functions/subscriptions/orm.go @@ -114,8 +114,13 @@ func (o *orm) UpsertSubscription(subscription StoredSubscription, qopts ...pg.QO subscription.Flags[:], o.routerContractAddress, ) + if err != nil { + return err + } + + o.lggr.Debugf("Successfully updated subscription: %d for routerContractAddress: %s", subscription.SubscriptionID, o.routerContractAddress) - return err + return nil } func (cs *storedSubscriptionRow) encode() StoredSubscription { diff --git a/core/store/migrate/migrations/0221_functions_allowlist.sql b/core/store/migrate/migrations/0221_functions_allowlist.sql index 6415344af18..148cecde594 100644 --- a/core/store/migrate/migrations/0221_functions_allowlist.sql +++ b/core/store/migrate/migrations/0221_functions_allowlist.sql @@ -2,13 +2,21 @@ -- +goose StatementBegin CREATE TABLE functions_allowlist( id BIGSERIAL, - router_contract_address bytea, + router_contract_address bytea CHECK (octet_length(router_contract_address) = 20) NOT NULL, allowed_address bytea CHECK (octet_length(allowed_address) = 20) NOT NULL, PRIMARY KEY(router_contract_address, allowed_address) ); + +ALTER TABLE functions_subscriptions +ADD CONSTRAINT router_contract_address_octet_lenth CHECK (octet_length(router_contract_address) = 20); + -- +goose StatementEnd -- +goose Down -- +goose StatementBegin + +ALTER TABLE functions_subscriptions +DROP CONSTRAINT router_contract_address_octet_lenth; + DROP TABLE IF EXISTS functions_allowlist; -- +goose StatementEnd From 2feab3a084932ebf8220f5c1001a2977deab3140 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Tue, 23 Jan 2024 12:45:17 +0100 Subject: [PATCH 22/23] chore: methods renaming --- .../handlers/functions/allowlist/allowlist.go | 12 ++++---- .../handlers/functions/handler.functions.go | 30 +++++++++---------- .../migrations/0221_functions_allowlist.sql | 4 +-- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist/allowlist.go b/core/services/gateway/handlers/functions/allowlist/allowlist.go index 5d031a7834b..20dc92ced70 100644 --- a/core/services/gateway/handlers/functions/allowlist/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist/allowlist.go @@ -220,12 +220,12 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b return errors.Wrap(err, "error calling GetAllAllowedSenders") } } else { - err = a.syncStoredAllowedAndBlockedSenders(ctx, tosContract, blockNum) + err = a.syncBlockedSenders(ctx, tosContract, blockNum) if err != nil { return errors.Wrap(err, "failed to sync the stored allowed and blocked senders") } - allowedSenderList, err = a.getAllowedSendersInRange(ctx, tosContract, blockNum) + allowedSenderList, err = a.getAllowedSendersBatched(ctx, tosContract, blockNum) if err != nil { return errors.Wrap(err, "failed to get allowed senders in rage") } @@ -235,7 +235,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b return nil } -func (a *onchainAllowlist) getAllowedSendersInRange(ctx context.Context, tosContract *functions_allow_list.TermsOfServiceAllowList, blockNum *big.Int) ([]common.Address, error) { +func (a *onchainAllowlist) getAllowedSendersBatched(ctx context.Context, tosContract *functions_allow_list.TermsOfServiceAllowList, blockNum *big.Int) ([]common.Address, error) { allowedSenderList := make([]common.Address, 0) count, err := tosContract.GetAllowedSendersCount(&bind.CallOpts{ Pending: false, @@ -275,9 +275,9 @@ func (a *onchainAllowlist) getAllowedSendersInRange(ctx context.Context, tosCont return allowedSenderList, nil } -// syncStoredAllowedAndBlockedSenders fetches the list of blocked addresses from the contract in batches +// syncBlockedSenders fetches the list of blocked addresses from the contract in batches // and removes the addresses from the functions_allowlist table if present -func (a *onchainAllowlist) syncStoredAllowedAndBlockedSenders(ctx context.Context, tosContract *functions_allow_list.TermsOfServiceAllowList, blockNum *big.Int) error { +func (a *onchainAllowlist) syncBlockedSenders(ctx context.Context, tosContract *functions_allow_list.TermsOfServiceAllowList, blockNum *big.Int) error { count, err := tosContract.GetBlockedSendersCount(&bind.CallOpts{ Pending: false, BlockNumber: blockNum, @@ -336,7 +336,7 @@ func (a *onchainAllowlist) loadStoredAllowedSenderList() { allowedList = append(allowedList, asBatch...) - if len(asBatch) != int(a.config.StoredAllowlistBatchSize) { + if len(asBatch) < int(a.config.StoredAllowlistBatchSize) { break } offset += a.config.StoredAllowlistBatchSize diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go index 118ed4b7dec..ff272e4e577 100644 --- a/core/services/gateway/handlers/functions/handler.functions.go +++ b/core/services/gateway/handlers/functions/handler.functions.go @@ -23,8 +23,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/config" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers" hc "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" - all "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" - sub "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" + fallow "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/allowlist" + fsub "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions/subscriptions" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -62,10 +62,10 @@ var ( type FunctionsHandlerConfig struct { ChainID string `json:"chainId"` // Not specifying OnchainAllowlist config disables allowlist checks - OnchainAllowlist *all.OnchainAllowlistConfig `json:"onchainAllowlist"` + OnchainAllowlist *fallow.OnchainAllowlistConfig `json:"onchainAllowlist"` // Not specifying OnchainSubscriptions config disables minimum balance checks - OnchainSubscriptions *sub.OnchainSubscriptionsConfig `json:"onchainSubscriptions"` - MinimumSubscriptionBalance *assets.Link `json:"minimumSubscriptionBalance"` + OnchainSubscriptions *fsub.OnchainSubscriptionsConfig `json:"onchainSubscriptions"` + MinimumSubscriptionBalance *assets.Link `json:"minimumSubscriptionBalance"` // Not specifying RateLimiter config disables rate limiting UserRateLimiter *hc.RateLimiterConfig `json:"userRateLimiter"` NodeRateLimiter *hc.RateLimiterConfig `json:"nodeRateLimiter"` @@ -81,8 +81,8 @@ type functionsHandler struct { donConfig *config.DONConfig don handlers.DON pendingRequests hc.RequestCache[PendingRequest] - allowlist all.OnchainAllowlist - subscriptions sub.OnchainSubscriptions + allowlist fallow.OnchainAllowlist + subscriptions fsub.OnchainSubscriptions minimumBalance *assets.Link userRateLimiter *hc.RateLimiter nodeRateLimiter *hc.RateLimiter @@ -107,18 +107,18 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con return nil, err } lggr = lggr.Named("FunctionsHandler:" + donConfig.DonId) - var allowlist all.OnchainAllowlist + var allowlist fallow.OnchainAllowlist if cfg.OnchainAllowlist != nil { chain, err2 := legacyChains.Get(cfg.ChainID) if err2 != nil { return nil, err2 } - orm, err2 := all.NewORM(db, lggr, qcfg, cfg.OnchainAllowlist.ContractAddress) + orm, err2 := fallow.NewORM(db, lggr, qcfg, cfg.OnchainAllowlist.ContractAddress) if err2 != nil { return nil, err2 } - allowlist, err2 = all.NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, orm, lggr) + allowlist, err2 = fallow.NewOnchainAllowlist(chain.Client(), *cfg.OnchainAllowlist, orm, lggr) if err2 != nil { return nil, err2 } @@ -136,19 +136,19 @@ func NewFunctionsHandlerFromConfig(handlerConfig json.RawMessage, donConfig *con return nil, err } } - var subscriptions sub.OnchainSubscriptions + var subscriptions fsub.OnchainSubscriptions if cfg.OnchainSubscriptions != nil { chain, err2 := legacyChains.Get(cfg.ChainID) if err2 != nil { return nil, err2 } - orm, err2 := sub.NewORM(db, lggr, qcfg, cfg.OnchainSubscriptions.ContractAddress) + orm, err2 := fsub.NewORM(db, lggr, qcfg, cfg.OnchainSubscriptions.ContractAddress) if err2 != nil { return nil, err2 } - subscriptions, err2 = sub.NewOnchainSubscriptions(chain.Client(), *cfg.OnchainSubscriptions, orm, lggr) + subscriptions, err2 = fsub.NewOnchainSubscriptions(chain.Client(), *cfg.OnchainSubscriptions, orm, lggr) if err2 != nil { return nil, err2 } @@ -166,8 +166,8 @@ func NewFunctionsHandler( donConfig *config.DONConfig, don handlers.DON, pendingRequestsCache hc.RequestCache[PendingRequest], - allowlist all.OnchainAllowlist, - subscriptions sub.OnchainSubscriptions, + allowlist fallow.OnchainAllowlist, + subscriptions fsub.OnchainSubscriptions, minimumBalance *assets.Link, userRateLimiter *hc.RateLimiter, nodeRateLimiter *hc.RateLimiter, diff --git a/core/store/migrate/migrations/0221_functions_allowlist.sql b/core/store/migrate/migrations/0221_functions_allowlist.sql index 148cecde594..e97b2fc4077 100644 --- a/core/store/migrate/migrations/0221_functions_allowlist.sql +++ b/core/store/migrate/migrations/0221_functions_allowlist.sql @@ -8,7 +8,7 @@ CREATE TABLE functions_allowlist( ); ALTER TABLE functions_subscriptions -ADD CONSTRAINT router_contract_address_octet_lenth CHECK (octet_length(router_contract_address) = 20); +ADD CONSTRAINT router_contract_address_octet_length CHECK (octet_length(router_contract_address) = 20); -- +goose StatementEnd @@ -16,7 +16,7 @@ ADD CONSTRAINT router_contract_address_octet_lenth CHECK (octet_length(router_co -- +goose StatementBegin ALTER TABLE functions_subscriptions -DROP CONSTRAINT router_contract_address_octet_lenth; +DROP CONSTRAINT router_contract_address_octet_length; DROP TABLE IF EXISTS functions_allowlist; -- +goose StatementEnd From e3389640e717f6c315da4191770f21896ab20b83 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Wed, 24 Jan 2024 10:55:28 +0100 Subject: [PATCH 23/23] chore: correct log and var name --- .../gateway/handlers/functions/allowlist/orm.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/core/services/gateway/handlers/functions/allowlist/orm.go b/core/services/gateway/handlers/functions/allowlist/orm.go index 9ecbbf1feb0..07ee1ea3b3b 100644 --- a/core/services/gateway/handlers/functions/allowlist/orm.go +++ b/core/services/gateway/handlers/functions/allowlist/orm.go @@ -66,9 +66,9 @@ func (o *orm) GetAllowedSenders(offset, limit uint, qopts ...pg.QOpt) ([]common. return addresses, nil } -func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.QOpt) error { +func (o *orm) CreateAllowedSenders(allowedSenders []common.Address, qopts ...pg.QOpt) error { var valuesPlaceholder []string - for i := 1; i <= len(allowedSender)*2; i += 2 { + for i := 1; i <= len(allowedSenders)*2; i += 2 { valuesPlaceholder = append(valuesPlaceholder, fmt.Sprintf("($%d, $%d)", i, i+1)) } @@ -77,7 +77,7 @@ func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.Q VALUES %s ON CONFLICT (allowed_address, router_contract_address) DO NOTHING;`, tableName, strings.Join(valuesPlaceholder, ", ")) var args []interface{} - for _, as := range allowedSender { + for _, as := range allowedSenders { args = append(args, as, o.routerContractAddress) } @@ -86,7 +86,7 @@ func (o *orm) CreateAllowedSenders(allowedSender []common.Address, qopts ...pg.Q return err } - o.lggr.Debugf("Successfully stored allowed sender: %s for routerContractAddress: %s", allowedSender, o.routerContractAddress) + o.lggr.Debugf("Successfully stored allowed senders: %v for routerContractAddress: %s", allowedSenders, o.routerContractAddress) return nil } @@ -117,7 +117,7 @@ func (o *orm) DeleteAllowedSenders(blockedSenders []common.Address, qopts ...pg. return err } - o.lggr.Debugf("Successfully removed blocked senders from the allowed list: %s for routerContractAddress: %s. rowsAffected: %d", blockedSenders, o.routerContractAddress, rowsAffected) + o.lggr.Debugf("Successfully removed blocked senders from the allowed list: %v for routerContractAddress: %s. rowsAffected: %d", blockedSenders, o.routerContractAddress, rowsAffected) return nil }