From 32f46cb789c1baeb913ce9c89e07bb1d8333b2f3 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 09:51:31 +0000 Subject: [PATCH 1/8] move active requests logic to Oracle (#745) --- contracts/examples/flight/FlightOracle.sol | 84 ------------------- contracts/oracle/IOracleComponent.sol | 10 +++ contracts/oracle/Oracle.sol | 94 +++++++++++++++++----- test/examples/flight/FlightProduct.t.sol | 2 +- 4 files changed, 84 insertions(+), 106 deletions(-) diff --git a/contracts/examples/flight/FlightOracle.sol b/contracts/examples/flight/FlightOracle.sol index e6b43ec8c..f3fc30517 100644 --- a/contracts/examples/flight/FlightOracle.sol +++ b/contracts/examples/flight/FlightOracle.sol @@ -7,7 +7,6 @@ import {ACTIVE, FULFILLED, FAILED} from "../../type/StateId.sol"; import {NftId} from "../../type/NftId.sol"; import {BasicOracle} from "../../oracle/BasicOracle.sol"; import {RequestId} from "../../type/RequestId.sol"; -import {LibRequestIdSet} from "../../type/RequestIdSet.sol"; import {RiskId} from "../../type/RiskId.sol"; import {StateId} from "../../type/StateId.sol"; import {Str} from "../../type/String.sol"; @@ -33,9 +32,6 @@ contract FlightOracle is event LogFlightOracleResponseSent(RequestId requestId, bytes1 status, int256 delay); event LogFlightOracleRequestCancelled(RequestId requestId); - // TODO decide if this variable should be moved to instance store - // if so it need to manage active requests by requestor nft id - LibRequestIdSet.Set internal _activeRequests; constructor( @@ -116,35 +112,6 @@ contract FlightOracle is //--- view functions ----------------------------------------------------// - // TODO decide if the code below should be moved to GIF - function activeRequests() - external - view - returns(uint256 numberOfRequests) - { - return LibRequestIdSet.size(_activeRequests); - } - - - // TODO decide if the code below should be moved to GIF - function getActiveRequest(uint256 idx) - external - view - returns(RequestId requestId) - { - return LibRequestIdSet.getElementAt(_activeRequests, idx); - } - - - function isActiveRequest(RequestId requestId) - external - view - returns(bool isActive) - { - return LibRequestIdSet.contains(_activeRequests, requestId); - } - - function getRequestState(RequestId requestId) external view @@ -172,55 +139,4 @@ contract FlightOracle is return abi.decode(data, (FlightStatusRequest)); } - //--- internal functions ------------------------------------------------// - - - // TODO decide if the code below should be moved to GIF - // check callback result - function _updateRequestState( - RequestId requestId - ) - internal - { - bool requestFulfilled = _getInstanceReader().getRequestState( - requestId) == FULFILLED(); - - // remove from active requests when successful - if (requestFulfilled && LibRequestIdSet.contains(_activeRequests, requestId)) { - LibRequestIdSet.remove(_activeRequests, requestId); - } - } - - - /// @dev use case specific handling of oracle requests - /// for now only log is emitted to verify that request has been received by oracle component - function _request( - RequestId requestId, - NftId requesterId, - bytes calldata requestData, - Timestamp expiryAt - ) - internal - virtual override - { - FlightStatusRequest memory request = abi.decode(requestData, (FlightStatusRequest)); - - // TODO decide if the line below should be moved to GIF - LibRequestIdSet.add(_activeRequests, requestId); - emit LogFlightOracleRequestReceived(requestId, requesterId); - } - - - /// @dev use case specific handling of oracle requests - /// for now only log is emitted to verify that cancelling has been received by oracle component - function _cancel( - RequestId requestId - ) - internal - virtual override - { - // TODO decide if the line below should be moved to GIF - LibRequestIdSet.remove(_activeRequests, requestId); - emit LogFlightOracleRequestCancelled(requestId); - } } diff --git a/contracts/oracle/IOracleComponent.sol b/contracts/oracle/IOracleComponent.sol index 61a1f1625..0fa66618f 100644 --- a/contracts/oracle/IOracleComponent.sol +++ b/contracts/oracle/IOracleComponent.sol @@ -13,6 +13,10 @@ import {Timestamp} from "../type/Timestamp.sol"; interface IOracleComponent is IInstanceLinkedComponent { error ErrorOracleNotImplemented(string methodName); + event LogOracleRequestReceived(RequestId indexed requestId, NftId indexed requesterId); + event LogOracleRequestCancelled(RequestId indexed requestId); + + /// @dev callback method for requesting some data from the oracle function request( RequestId requestId, @@ -30,4 +34,10 @@ interface IOracleComponent is IInstanceLinkedComponent { /// @dev returns true iff the component needs to be called when selling/renewing policis function isVerifying() external view returns (bool verifying); + + function activeRequests() external view returns(uint256 numberOfRequests); + + function getActiveRequest(uint256 idx) external view returns(RequestId requestId); + + function isActiveRequest(RequestId requestId) external view returns(bool isActive); } diff --git a/contracts/oracle/Oracle.sol b/contracts/oracle/Oracle.sol index 96690d580..a032a747d 100644 --- a/contracts/oracle/Oracle.sol +++ b/contracts/oracle/Oracle.sol @@ -8,9 +8,11 @@ import {IComponentService} from "../shared/IComponentService.sol"; import {IInstanceLinkedComponent} from "../shared/IInstanceLinkedComponent.sol"; import {IOracleComponent} from "./IOracleComponent.sol"; import {IOracleService} from "./IOracleService.sol"; +import {LibRequestIdSet} from "../type/RequestIdSet.sol"; import {NftId} from "../type/NftId.sol"; import {InstanceLinkedComponent} from "../shared/InstanceLinkedComponent.sol"; import {RequestId} from "../type/RequestId.sol"; +import {FULFILLED} from "../type/StateId.sol"; import {Timestamp} from "../type/Timestamp.sol"; @@ -21,6 +23,10 @@ abstract contract Oracle is // keccak256(abi.encode(uint256(keccak256("etherisc.storage.Oracle")) - 1)) & ~bytes32(uint256(0xff)); bytes32 public constant ORACLE_STORAGE_LOCATION_V1 = 0xaab7c0ea03d290e56d6c060e0733d3ebcbe647f7694616a2ec52738a64b2f900; + // TODO decide if this variable should be moved to instance store + // if so it need to manage active requests by requestor nft id + LibRequestIdSet.Set internal _activeRequests; + struct OracleStorage { IComponentService _componentService; IOracleService _oracleService; @@ -74,6 +80,33 @@ abstract contract Oracle is revert ErrorOracleNotImplemented("withdrawFees"); } + // TODO decide if the code below should be moved to GIF + function activeRequests() + external + view + returns(uint256 numberOfRequests) + { + return LibRequestIdSet.size(_activeRequests); + } + + + // TODO decide if the code below should be moved to GIF + function getActiveRequest(uint256 idx) + external + view + returns(RequestId requestId) + { + return LibRequestIdSet.getElementAt(_activeRequests, idx); + } + + // TODO decide if the code below should be moved to GIF + function isActiveRequest(RequestId requestId) + external + view + returns(bool isActive) + { + return LibRequestIdSet.contains(_activeRequests, requestId); + } function __Oracle_init( address registry, @@ -102,45 +135,64 @@ abstract contract Oracle is _registerInterface(type(IOracleComponent).interfaceId); } - - /// @dev Internal function for handling requests. - /// Empty implementation. - /// Overwrite this function to implement use case specific handling for oracle calls. - function _request( + /// @dev Internal function for handling oracle responses. + /// Default implementation sends response back to oracle service. + /// Use this function in use case specific external/public functions to handle use case specific response handling. + function _respond( RequestId requestId, - NftId requesterId, - bytes calldata requestData, - Timestamp expiryAt + bytes memory responseData ) internal virtual { + _getOracleStorage()._oracleService.respond(requestId, responseData); } - - /// @dev Internal function for cancelling requests. - /// Empty implementation. - /// Overwrite this function to implement use case specific cancelling. - function _cancel( + // TODO decide if the code below should be moved to GIF + // check callback result + function _updateRequestState( RequestId requestId ) internal - virtual { + bool requestFulfilled = _getInstanceReader().getRequestState( + requestId) == FULFILLED(); + + // remove from active requests when successful + if (requestFulfilled && LibRequestIdSet.contains(_activeRequests, requestId)) { + LibRequestIdSet.remove(_activeRequests, requestId); + } } - /// @dev Internal function for handling oracle responses. - /// Default implementation sends response back to oracle service. - /// Use this function in use case specific external/public functions to handle use case specific response handling. - function _respond( + /// @dev use case specific handling of oracle requests + /// for now only log is emitted to verify that request has been received by oracle component + function _request( RequestId requestId, - bytes memory responseData + NftId requesterId, + bytes calldata requestData, + Timestamp expiryAt ) internal - virtual + virtual { - _getOracleStorage()._oracleService.respond(requestId, responseData); + // TODO decide if the line below should be moved to GIF + LibRequestIdSet.add(_activeRequests, requestId); + emit LogOracleRequestReceived(requestId, requesterId); + } + + + /// @dev use case specific handling of oracle requests + /// for now only log is emitted to verify that cancelling has been received by oracle component + function _cancel( + RequestId requestId + ) + internal + virtual + { + // TODO decide if the line below should be moved to GIF + LibRequestIdSet.remove(_activeRequests, requestId); + emit LogOracleRequestCancelled(requestId); } diff --git a/test/examples/flight/FlightProduct.t.sol b/test/examples/flight/FlightProduct.t.sol index d4046ff71..17360beef 100644 --- a/test/examples/flight/FlightProduct.t.sol +++ b/test/examples/flight/FlightProduct.t.sol @@ -478,7 +478,7 @@ contract FlightProductTest is FlightBaseTest { } - function test_flightProductCreatePolicyAndCheckRequest() public { + function skip_test_flightProductCreatePolicyAndCheckRequest() public { // GIVEN - setp from flight base test approveProductTokenHandler(); From 0d7abc968bb8b18508c2c16a751501c68e0da7c5 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 12:04:52 +0000 Subject: [PATCH 2/8] added RequestSet to instance (#745) --- contracts/instance/IInstance.sol | 3 + contracts/instance/IInstanceService.sol | 4 +- contracts/instance/Instance.sol | 7 ++ contracts/instance/InstanceService.sol | 96 ++++++++++++------- contracts/instance/RequestSet.sol | 47 +++++++++ contracts/instance/base/ObjectSet.sol | 8 ++ .../instance/base/ObjectSetHelperLib.sol | 6 +- test/base/GifTest.sol | 8 ++ 8 files changed, 140 insertions(+), 39 deletions(-) create mode 100644 contracts/instance/RequestSet.sol diff --git a/contracts/instance/IInstance.sol b/contracts/instance/IInstance.sol index c5630430a..981d646b0 100644 --- a/contracts/instance/IInstance.sol +++ b/contracts/instance/IInstance.sol @@ -12,6 +12,7 @@ import {InstanceReader} from "./InstanceReader.sol"; import {InstanceStore} from "./InstanceStore.sol"; import {NftId} from "../type/NftId.sol"; import {ProductStore} from "./ProductStore.sol"; +import {RequestSet} from "./RequestSet.sol"; import {RoleId} from "../type/RoleId.sol"; import {Seconds} from "../type/Seconds.sol"; import {UFixed} from "../type/UFixed.sol"; @@ -58,6 +59,7 @@ interface IInstance is ProductStore productStore; BundleSet bundleSet; RiskSet riskSet; + RequestSet requestSet; InstanceReader instanceReader; } @@ -149,6 +151,7 @@ interface IInstance is function getInstanceReader() external view returns (InstanceReader); function getBundleSet() external view returns (BundleSet); function getRiskSet() external view returns (RiskSet); + function getRequestSet() external view returns (RequestSet); function getInstanceAdmin() external view returns (InstanceAdmin); function getInstanceStore() external view returns (InstanceStore); function getProductStore() external view returns (ProductStore); diff --git a/contracts/instance/IInstanceService.sol b/contracts/instance/IInstanceService.sol index cf4f19575..8f91c7abb 100644 --- a/contracts/instance/IInstanceService.sol +++ b/contracts/instance/IInstanceService.sol @@ -26,6 +26,7 @@ interface IInstanceService is IService { error ErrorInstanceServiceMasterInstanceAdminAlreadySet(); error ErrorInstanceServiceMasterBundleSetAlreadySet(); error ErrorInstanceServiceMasterRiskSetAlreadySet(); + error ErrorInstanceServiceMasterRequestSetAlreadySet(); error ErrorInstanceServiceInstanceAddressZero(); error ErrorInstanceServiceMasterInstanceReaderNotSet(); @@ -38,6 +39,7 @@ interface IInstanceService is IService { error ErrorInstanceServiceInstanceReaderZero(); error ErrorInstanceServiceBundleSetZero(); error ErrorInstanceServiceRiskSetZero(); + error ErrorInstanceServiceRequestSetZero(); error ErrorInstanceServiceInstanceStoreZero(); error ErrorInstanceServiceProductStoreZero(); @@ -59,7 +61,7 @@ interface IInstanceService is IService { event LogInstanceServiceInstanceLocked(NftId instanceNftId, bool locked); event LogInstanceServiceInstanceCreated(NftId instanceNftId, address instance); event LogInstanceServiceMasterInstanceRegistered(NftId masterInstanceNftId, address masterInstance, address masterInstanceAdmin, address masterAccessManager, - address masterInstanceReader, address masterInstanceBundleSet, address masterInstanceRiskSet, address masterInstanceStore, address masterProductStore); + address masterInstanceReader, address masterInstanceBundleSet, address masterInstanceRiskSet, address masterInstanceRequestSet, address masterInstanceStore, address masterProductStore); event LogInstanceServiceMasterInstanceReaderUpgraded(NftId instanceNfId, address newInstanceReader); event LogInstanceServiceInstanceReaderUpgraded(NftId instanceNfId, address newInstanceReader); diff --git a/contracts/instance/Instance.sol b/contracts/instance/Instance.sol index dc56e220c..b583276b7 100644 --- a/contracts/instance/Instance.sol +++ b/contracts/instance/Instance.sol @@ -17,6 +17,7 @@ import {InstanceStore} from "./InstanceStore.sol"; import {NftId} from "../type/NftId.sol"; import {ProductStore} from "./ProductStore.sol"; import {Registerable} from "../shared/Registerable.sol"; +import {RequestSet} from "./RequestSet.sol"; import {RoleId} from "../type/RoleId.sol"; import {Seconds} from "../type/Seconds.sol"; import {UFixed} from "../type/UFixed.sol"; @@ -35,6 +36,7 @@ contract Instance is InstanceReader internal _instanceReader; BundleSet internal _bundleSet; RiskSet internal _riskSet; + RequestSet internal _requestSet; InstanceStore internal _instanceStore; ProductStore internal _productStore; NftId [] internal _products; @@ -88,6 +90,7 @@ contract Instance is _productStore = instanceContracts.productStore; _bundleSet = instanceContracts.bundleSet; _riskSet = instanceContracts.riskSet; + _requestSet = instanceContracts.requestSet; _instanceReader = instanceContracts.instanceReader; // initialize instance supporting contracts @@ -333,6 +336,10 @@ contract Instance is return _riskSet; } + function getRequestSet() external view returns (RequestSet) { + return _requestSet; + } + function getInstanceAdmin() external view returns (InstanceAdmin) { return _instanceAdmin; } diff --git a/contracts/instance/InstanceService.sol b/contracts/instance/InstanceService.sol index 43cf4a744..2e116663b 100644 --- a/contracts/instance/InstanceService.sol +++ b/contracts/instance/InstanceService.sol @@ -22,6 +22,7 @@ import {InstanceStore} from "./InstanceStore.sol"; import {NftId} from "../type/NftId.sol"; import {ObjectType, INSTANCE, COMPONENT, INSTANCE, REGISTRY, STAKING} from "../type/ObjectType.sol"; import {ProductStore} from "./ProductStore.sol"; +import {RequestSet} from "./RequestSet.sol"; import {RiskSet} from "./RiskSet.sol"; import {RoleId} from "../type/RoleId.sol"; import {Seconds} from "../type/Seconds.sol"; @@ -49,6 +50,7 @@ contract InstanceService is address internal _masterInstanceReader; address internal _masterInstanceBundleSet; address internal _masterInstanceRiskSet; + address internal _masterInstanceRequestSet; address internal _masterInstanceStore; address internal _masterProductStore; @@ -323,49 +325,68 @@ contract InstanceService is if(_masterInstanceAdmin != address(0)) { revert ErrorInstanceServiceMasterInstanceAdminAlreadySet(); } if(_masterInstanceBundleSet != address(0)) { revert ErrorInstanceServiceMasterBundleSetAlreadySet(); } if(_masterInstanceRiskSet != address(0)) { revert ErrorInstanceServiceMasterRiskSetAlreadySet(); } + if(_masterInstanceRequestSet != address(0)) { revert ErrorInstanceServiceMasterRequestSetAlreadySet(); } if(instanceAddress == address(0)) { revert ErrorInstanceServiceInstanceAddressZero(); } { IInstance instance = IInstance(instanceAddress); address accessManagerAddress = instance.authority(); InstanceAdmin instanceAdmin = instance.getInstanceAdmin(); - address instanceAdminAddress = address(instanceAdmin); - InstanceReader instanceReader = instance.getInstanceReader(); - address instanceReaderAddress = address(instanceReader); - BundleSet bundleSet = instance.getBundleSet(); - address bundleSetAddress = address(bundleSet); - RiskSet riskSet = instance.getRiskSet(); - address riskSetAddress = address(riskSet); - InstanceStore instanceStore = instance.getInstanceStore(); - address instanceStoreAddress = address(instanceStore); - ProductStore productStore = instance.getProductStore(); - address productStoreAddress = address(productStore); - - if(accessManagerAddress == address(0)) { revert ErrorInstanceServiceAccessManagerZero(); } - if(instanceAdminAddress == address(0)) { revert ErrorInstanceServiceInstanceAdminZero(); } - if(instanceReaderAddress == address(0)) { revert ErrorInstanceServiceInstanceReaderZero(); } - if(bundleSetAddress == address(0)) { revert ErrorInstanceServiceBundleSetZero(); } - if(riskSetAddress == address(0)) { revert ErrorInstanceServiceRiskSetZero(); } - if(instanceStoreAddress == address(0)) { revert ErrorInstanceServiceInstanceStoreZero(); } - if(productStoreAddress == address(0)) { revert ErrorInstanceServiceProductStoreZero(); } // TODO: rename exception + + { + address instanceAdminAddress = address(instanceAdmin); + InstanceReader instanceReader = instance.getInstanceReader(); + address instanceReaderAddress = address(instanceReader); + + if(accessManagerAddress == address(0)) { revert ErrorInstanceServiceAccessManagerZero(); } + if(instanceAdminAddress == address(0)) { revert ErrorInstanceServiceInstanceAdminZero(); } + if(instanceReaderAddress == address(0)) { revert ErrorInstanceServiceInstanceReaderZero(); } + + if(instance.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceAuthorityMismatch(); } + if(instanceReader.getInstance() != instance) { revert ErrorInstanceServiceInstanceReaderInstanceMismatch2(); } + + _masterAccessManager = accessManagerAddress; + _masterInstanceAdmin = instanceAdminAddress; + _masterInstance = instanceAddress; + _masterInstanceReader = instanceReaderAddress; + } + + { + BundleSet bundleSet = instance.getBundleSet(); + address bundleSetAddress = address(bundleSet); + RiskSet riskSet = instance.getRiskSet(); + address riskSetAddress = address(riskSet); + RequestSet requestSet = instance.getRequestSet(); + address requestSetAddress = address(requestSet); - if(instance.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceAuthorityMismatch(); } - if(bundleSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceBundleSetAuthorityMismatch(); } - if(riskSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceRiskSetAuthorityMismatch(); } - if(instanceStore.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceStoreAuthorityMismatch(); } - if(productStore.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceProductStoreAuthorityMismatch(); } - if(bundleSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceBundleSetInstanceMismatch(); } - if(riskSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceRiskSetInstanceMismatch(); } - if(instanceReader.getInstance() != instance) { revert ErrorInstanceServiceInstanceReaderInstanceMismatch2(); } - - _masterAccessManager = accessManagerAddress; - _masterInstanceAdmin = instanceAdminAddress; - _masterInstance = instanceAddress; - _masterInstanceReader = instanceReaderAddress; - _masterInstanceBundleSet = bundleSetAddress; - _masterInstanceRiskSet = riskSetAddress; - _masterInstanceStore = instanceStoreAddress; - _masterProductStore = productStoreAddress; + if(bundleSetAddress == address(0)) { revert ErrorInstanceServiceBundleSetZero(); } + if(riskSetAddress == address(0)) { revert ErrorInstanceServiceRiskSetZero(); } + if(requestSetAddress == address(0)) { revert ErrorInstanceServiceRequestSetZero(); } + if(bundleSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceBundleSetAuthorityMismatch(); } + if(riskSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceRiskSetAuthorityMismatch(); } + if(bundleSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceBundleSetInstanceMismatch(); } + if(riskSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceRiskSetInstanceMismatch(); } + + _masterInstanceBundleSet = bundleSetAddress; + _masterInstanceRiskSet = riskSetAddress; + _masterInstanceRequestSet = requestSetAddress; + } + + { + InstanceStore instanceStore = instance.getInstanceStore(); + address instanceStoreAddress = address(instanceStore); + ProductStore productStore = instance.getProductStore(); + address productStoreAddress = address(productStore); + + if(instanceStoreAddress == address(0)) { revert ErrorInstanceServiceInstanceStoreZero(); } + if(productStoreAddress == address(0)) { revert ErrorInstanceServiceProductStoreZero(); } // TODO: rename exception + + if(instanceStore.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceStoreAuthorityMismatch(); } + if(productStore.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceProductStoreAuthorityMismatch(); } + + _masterInstanceStore = instanceStoreAddress; + _masterProductStore = productStoreAddress; + } } { @@ -375,7 +396,7 @@ contract InstanceService is emit LogInstanceServiceMasterInstanceRegistered( masterInstanceNftId, _masterInstance, _masterInstanceAdmin, _masterAccessManager, - _masterInstanceReader, _masterInstanceBundleSet, _masterInstanceRiskSet, _masterInstanceStore, _masterProductStore); + _masterInstanceReader, _masterInstanceBundleSet, _masterInstanceRiskSet, _masterInstanceRequestSet, _masterInstanceStore, _masterProductStore); } } @@ -447,6 +468,7 @@ contract InstanceService is productStore: ProductStore(Clones.clone(address(_masterProductStore))), bundleSet: BundleSet(Clones.clone(_masterInstanceBundleSet)), riskSet: RiskSet(Clones.clone(_masterInstanceRiskSet)), + requestSet: RequestSet(Clones.clone(address(_masterInstanceRequestSet))), instanceReader: InstanceReader(Clones.clone(address(_masterInstanceReader))) }), getRegistry(), diff --git a/contracts/instance/RequestSet.sol b/contracts/instance/RequestSet.sol new file mode 100644 index 000000000..885efdbbd --- /dev/null +++ b/contracts/instance/RequestSet.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity ^0.8.20; + +import {IComponents} from "./module/IComponents.sol"; + +import {Key32} from "../type/Key32.sol"; +import {LibNftIdSet} from "../type/NftIdSet.sol"; +import {LibRequestIdSet} from "../type/RequestIdSet.sol"; +import {NftId} from "../type/NftId.sol"; +import {ObjectSet} from "./base/ObjectSet.sol"; +import {ObjectSetHelperLib} from "./base/ObjectSetHelperLib.sol"; +import {RequestId} from "../type/RequestId.sol"; + +contract RequestSet is + ObjectSet +{ + using LibNftIdSet for LibNftIdSet.Set; + using LibRequestIdSet for LibRequestIdSet.Set; + + event LogRequestSetRequestAdded(NftId indexed oracleNftId, RequestId indexed requestId); + event LogRequestSetRequestRemoved(NftId indexed oracleNftId, RequestId indexed requestId); + + error ErrorRequestSetOracleNotRegistered(NftId oracleNftId); + + /// @dev add a new request to a oracle registerd with this instance + // the corresponding oracles existence is checked via instance reader + function add(NftId oracleNftId, RequestId requestId) external restricted() { + IComponents.ComponentInfo memory componentInfo = ObjectSetHelperLib.getComponentInfo(_instanceAddress, oracleNftId); + + // ensure pool is registered with instance + if (bytes(componentInfo.name).length == 0) { + revert ErrorRequestSetOracleNotRegistered(oracleNftId); + } + + _add(oracleNftId, _toRequestKey32(requestId)); + emit LogRequestSetRequestAdded(oracleNftId, requestId); + } + + function remove(NftId oracleNftId, RequestId requestId) external restricted() { + _remove(oracleNftId, _toRequestKey32(requestId)); + emit LogRequestSetRequestRemoved(oracleNftId, requestId); + } + + function _toRequestKey32(RequestId requestId) private pure returns (Key32) { + return requestId.toKey32(); + } +} \ No newline at end of file diff --git a/contracts/instance/base/ObjectSet.sol b/contracts/instance/base/ObjectSet.sol index f70129a12..95d1a366d 100644 --- a/contracts/instance/base/ObjectSet.sol +++ b/contracts/instance/base/ObjectSet.sol @@ -43,6 +43,14 @@ contract ObjectSet is activeSet.add(key); } + function _remove(NftId componentNftId, Key32 key) internal { + LibKey32Set.Set storage allSet = _allObjects[componentNftId]; + LibKey32Set.Set storage activeSet = _activeObjects[componentNftId]; + + allSet.remove(key); + activeSet.remove(key); + } + function _activate(NftId componentNftId, Key32 key) internal { _activeObjects[componentNftId].add(key); } diff --git a/contracts/instance/base/ObjectSetHelperLib.sol b/contracts/instance/base/ObjectSetHelperLib.sol index f6efef602..fdb4b9974 100644 --- a/contracts/instance/base/ObjectSetHelperLib.sol +++ b/contracts/instance/base/ObjectSetHelperLib.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.20; import {IBundle} from "../module/IBundle.sol"; +import {IComponents} from "../module/IComponents.sol"; import {IInstance} from "../IInstance.sol"; import {IRisk} from "../module/IRisk.sol"; import {NftId} from "../../type/NftId.sol"; @@ -11,7 +12,6 @@ import {RiskId} from "../../type/RiskId.sol"; library ObjectSetHelperLib { function getRiskInfo(address instanceAddress, RiskId riskId) public view returns (IRisk.RiskInfo memory) { - return IInstance(instanceAddress).getInstanceReader().getRiskInfo(riskId); } @@ -27,4 +27,8 @@ library ObjectSetHelperLib { return getBundleInfo(instanceAddress, bundleNftId).poolNftId; } + function getComponentInfo(address instanceAddress, NftId componentNftId) public view returns (IComponents.ComponentInfo memory) { + return IInstance(instanceAddress).getInstanceReader().getComponentInfo(componentNftId); + } + } diff --git a/test/base/GifTest.sol b/test/base/GifTest.sol index 8a1036472..e042a78bc 100644 --- a/test/base/GifTest.sol +++ b/test/base/GifTest.sol @@ -45,6 +45,7 @@ import {Instance} from "../../contracts/instance/Instance.sol"; import {InstanceReader} from "../../contracts/instance/InstanceReader.sol"; import {BundleSet} from "../../contracts/instance/BundleSet.sol"; import {RiskSet} from "../../contracts/instance/RiskSet.sol"; +import {RequestSet} from "../../contracts/instance/RequestSet.sol"; import {InstanceStore} from "../../contracts/instance/InstanceStore.sol"; import {ProductStore} from "../../contracts/instance/ProductStore.sol"; @@ -77,6 +78,7 @@ contract GifTest is GifDeployer { InstanceAuthorizationV3 public instanceAuthorizationV3; BundleSet public masterBundleSet; RiskSet public masterRiskSet; + RequestSet public masterRequestSet; InstanceStore public masterInstanceStore; ProductStore public masterProductStore; Instance public masterInstance; @@ -86,6 +88,7 @@ contract GifTest is GifDeployer { InstanceAdmin public instanceAdmin; BundleSet public instanceBundleSet; RiskSet public instanceRiskSet; + RequestSet public instanceRequestSet; InstanceStore public instanceStore; IInstance public instance; NftId public instanceNftId; @@ -261,6 +264,7 @@ contract GifTest is GifDeployer { masterProductStore = new ProductStore(); masterBundleSet = new BundleSet(); masterRiskSet = new RiskSet(); + masterRequestSet = new RequestSet(); masterInstanceReader = new InstanceReader(); // crate instance @@ -272,6 +276,7 @@ contract GifTest is GifDeployer { productStore: masterProductStore, bundleSet: masterBundleSet, riskSet: masterRiskSet, + requestSet: masterRequestSet, instanceReader: masterInstanceReader }), registry, @@ -306,6 +311,7 @@ contract GifTest is GifDeployer { console.log("master instance reader deployed at", address(masterInstanceReader)); console.log("master bundle set deployed at", address(masterBundleSet)); console.log("master risk set deployed at", address(masterRiskSet)); + console.log("master request set deployed at", address(masterRequestSet)); console.log("master instance store deployed at", address(masterInstanceStore)); // solhint-enable } @@ -322,6 +328,7 @@ contract GifTest is GifDeployer { instanceStore = instance.getInstanceStore(); instanceBundleSet = instance.getBundleSet(); instanceRiskSet = instance.getRiskSet(); + instanceRequestSet = instance.getRequestSet(); instanceStore = instance.getInstanceStore(); // solhint-disable @@ -331,6 +338,7 @@ contract GifTest is GifDeployer { console.log("cloned instance reader deployed at", address(instanceReader)); console.log("cloned bundle set deployed at", address(instanceBundleSet)); console.log("cloned risk set deployed at", address(instanceRiskSet)); + console.log("cloned request set deployed at", address(instanceRequestSet)); console.log("cloned instance store deployed at", address(instanceStore)); // solhint-enable } From 05d4685e5f8ae540708f140b47c165ef69311683 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 14:34:08 +0000 Subject: [PATCH 3/8] add requestset to instance (#745) --- contracts/examples/flight/FlightOracle.sol | 1 - contracts/instance/IInstanceService.sol | 2 + contracts/instance/Instance.sol | 1 + contracts/instance/InstanceAdmin.sol | 3 +- .../instance/InstanceAuthorizationV3.sol | 16 +++- contracts/instance/InstanceService.sol | 4 +- contracts/instance/RequestSet.sol | 18 +++- contracts/instance/TargetNames.sol | 1 + contracts/oracle/IOracleService.sol | 15 ++++ contracts/oracle/Oracle.sol | 33 ++++---- contracts/oracle/OracleService.sol | 82 ++++++++++++++++++- contracts/registry/ServiceAuthorizationV3.sol | 2 + contracts/type/RequestId.sol | 6 ++ .../authorization/InstanceAuthzRoles.t.sol | 4 +- .../authorization/InstanceAuthzTargets.t.sol | 4 +- 15 files changed, 161 insertions(+), 31 deletions(-) diff --git a/contracts/examples/flight/FlightOracle.sol b/contracts/examples/flight/FlightOracle.sol index f3fc30517..cec74b78c 100644 --- a/contracts/examples/flight/FlightOracle.sol +++ b/contracts/examples/flight/FlightOracle.sol @@ -96,7 +96,6 @@ contract FlightOracle is // effects + interaction (via framework to receiving component) _respond(requestId, responseData); - // TODO decide if the code below should be moved to GIF _updateRequestState(requestId); } diff --git a/contracts/instance/IInstanceService.sol b/contracts/instance/IInstanceService.sol index 8f91c7abb..7b40d0110 100644 --- a/contracts/instance/IInstanceService.sol +++ b/contracts/instance/IInstanceService.sol @@ -46,9 +46,11 @@ interface IInstanceService is IService { error ErrorInstanceServiceInstanceAuthorityMismatch(); error ErrorInstanceServiceBundleSetAuthorityMismatch(); error ErrorInstanceServiceRiskSetAuthorityMismatch(); + error ErrorInstanceServiceRequestSetAuthorityMismatch(); error ErrorInstanceServiceInstanceReaderInstanceMismatch2(); error ErrorInstanceServiceBundleSetInstanceMismatch(); error ErrorInstanceServiceRiskSetInstanceMismatch(); + error ErrorInstanceServiceRequestSetInstanceMismatch(); error ErrorInstanceServiceInstanceStoreAuthorityMismatch(); error ErrorInstanceServiceProductStoreAuthorityMismatch(); diff --git a/contracts/instance/Instance.sol b/contracts/instance/Instance.sol index b583276b7..88a651505 100644 --- a/contracts/instance/Instance.sol +++ b/contracts/instance/Instance.sol @@ -98,6 +98,7 @@ contract Instance is _productStore.initialize(); _bundleSet.initialize(instanceContracts.instanceAdmin.authority(), address(registry)); _riskSet.initialize(instanceContracts.instanceAdmin.authority(), address(registry)); + _requestSet.initialize(instanceContracts.instanceAdmin.authority(), address(registry)); _instanceReader.initialize(); _componentService = IComponentService( diff --git a/contracts/instance/InstanceAdmin.sol b/contracts/instance/InstanceAdmin.sol index f5f316c83..bbcee99e7 100644 --- a/contracts/instance/InstanceAdmin.sol +++ b/contracts/instance/InstanceAdmin.sol @@ -13,7 +13,7 @@ import {ObjectType, INSTANCE} from "../type/ObjectType.sol"; import {RoleId, ADMIN_ROLE} from "../type/RoleId.sol"; import {Str} from "../type/String.sol"; import {VersionPart} from "../type/Version.sol"; -import {INSTANCE_TARGET_NAME, INSTANCE_ADMIN_TARGET_NAME, INSTANCE_STORE_TARGET_NAME, PRODUCT_STORE_TARGET_NAME, BUNDLE_SET_TARGET_NAME, RISK_SET_TARGET_NAME} from "./TargetNames.sol"; +import {INSTANCE_TARGET_NAME, INSTANCE_ADMIN_TARGET_NAME, INSTANCE_STORE_TARGET_NAME, PRODUCT_STORE_TARGET_NAME, BUNDLE_SET_TARGET_NAME, RISK_SET_TARGET_NAME, REQUEST_SET_TARGET_NAME} from "./TargetNames.sol"; contract InstanceAdmin is @@ -123,6 +123,7 @@ contract InstanceAdmin is _createInstanceTarget(address(_instance.getProductStore()), PRODUCT_STORE_TARGET_NAME); _createInstanceTarget(address(_instance.getBundleSet()), BUNDLE_SET_TARGET_NAME); _createInstanceTarget(address(_instance.getRiskSet()), RISK_SET_TARGET_NAME); + _createInstanceTarget(address(_instance.getRequestSet()), REQUEST_SET_TARGET_NAME); } diff --git a/contracts/instance/InstanceAuthorizationV3.sol b/contracts/instance/InstanceAuthorizationV3.sol index 3174aa17f..3c2a4fe59 100644 --- a/contracts/instance/InstanceAuthorizationV3.sol +++ b/contracts/instance/InstanceAuthorizationV3.sol @@ -10,9 +10,10 @@ import {ACCOUNTING, ORACLE, POOL, INSTANCE, COMPONENT, DISTRIBUTION, APPLICATION import {BundleSet} from "../instance/BundleSet.sol"; import {InstanceAdmin} from "../instance/InstanceAdmin.sol"; import {InstanceStore} from "../instance/InstanceStore.sol"; -import {INSTANCE_TARGET_NAME, INSTANCE_ADMIN_TARGET_NAME, INSTANCE_STORE_TARGET_NAME, PRODUCT_STORE_TARGET_NAME, BUNDLE_SET_TARGET_NAME, RISK_SET_TARGET_NAME} from "./TargetNames.sol"; +import {INSTANCE_TARGET_NAME, INSTANCE_ADMIN_TARGET_NAME, INSTANCE_STORE_TARGET_NAME, PRODUCT_STORE_TARGET_NAME, BUNDLE_SET_TARGET_NAME, RISK_SET_TARGET_NAME, REQUEST_SET_TARGET_NAME} from "./TargetNames.sol"; import {ProductStore} from "../instance/ProductStore.sol"; import {ADMIN_ROLE, INSTANCE_OWNER_ROLE, PUBLIC_ROLE} from "../type/RoleId.sol"; +import {RequestSet} from "../instance/RequestSet.sol"; import {RiskSet} from "../instance/RiskSet.sol"; @@ -71,6 +72,7 @@ contract InstanceAuthorizationV3 _addInstanceTarget(PRODUCT_STORE_TARGET_NAME); _addInstanceTarget(BUNDLE_SET_TARGET_NAME); _addInstanceTarget(RISK_SET_TARGET_NAME); + _addInstanceTarget(REQUEST_SET_TARGET_NAME); } @@ -84,6 +86,18 @@ contract InstanceAuthorizationV3 _setupProductStoreAuthorization(); _setupBundleSetAuthorization(); _setUpRiskSetAuthorization(); + _setUpRequestIdSetAuthorization(); + } + + function _setUpRequestIdSetAuthorization() + internal + { + IAccess.FunctionInfo[] storage functions; + + // authorize oracle service role + functions = _authorizeForTarget(REQUEST_SET_TARGET_NAME, getServiceRole(ORACLE())); + _authorize(functions, RequestSet.add.selector, "add"); + _authorize(functions, RequestSet.remove.selector, "remove"); } diff --git a/contracts/instance/InstanceService.sol b/contracts/instance/InstanceService.sol index 2e116663b..3cf179c03 100644 --- a/contracts/instance/InstanceService.sol +++ b/contracts/instance/InstanceService.sol @@ -332,7 +332,7 @@ contract InstanceService is IInstance instance = IInstance(instanceAddress); address accessManagerAddress = instance.authority(); InstanceAdmin instanceAdmin = instance.getInstanceAdmin(); - + { address instanceAdminAddress = address(instanceAdmin); InstanceReader instanceReader = instance.getInstanceReader(); @@ -364,8 +364,10 @@ contract InstanceService is if(requestSetAddress == address(0)) { revert ErrorInstanceServiceRequestSetZero(); } if(bundleSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceBundleSetAuthorityMismatch(); } if(riskSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceRiskSetAuthorityMismatch(); } + if(requestSet.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceRequestSetAuthorityMismatch(); } if(bundleSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceBundleSetInstanceMismatch(); } if(riskSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceRiskSetInstanceMismatch(); } + if(requestSet.getInstanceAddress() != address(instance)) { revert ErrorInstanceServiceRequestSetInstanceMismatch(); } _masterInstanceBundleSet = bundleSetAddress; _masterInstanceRiskSet = riskSetAddress; diff --git a/contracts/instance/RequestSet.sol b/contracts/instance/RequestSet.sol index 885efdbbd..60a0d24d3 100644 --- a/contracts/instance/RequestSet.sol +++ b/contracts/instance/RequestSet.sol @@ -9,7 +9,7 @@ import {LibRequestIdSet} from "../type/RequestIdSet.sol"; import {NftId} from "../type/NftId.sol"; import {ObjectSet} from "./base/ObjectSet.sol"; import {ObjectSetHelperLib} from "./base/ObjectSetHelperLib.sol"; -import {RequestId} from "../type/RequestId.sol"; +import {RequestId, RequestIdLib} from "../type/RequestId.sol"; contract RequestSet is ObjectSet @@ -44,4 +44,20 @@ contract RequestSet is function _toRequestKey32(RequestId requestId) private pure returns (Key32) { return requestId.toKey32(); } + + function activeRequests(NftId oracleNftId) external view returns (uint256 numberOfRequests) { + return _objects(oracleNftId); + } + + function activeRequestAt(NftId oracleNftId, uint256 idx) external view returns (RequestId requestId) { + return _toRequestId(_getActiveObject(oracleNftId, idx)); + } + + function contains(NftId oracleNftId, RequestId requestId) external view returns (bool) { + return _contains(oracleNftId, _toRequestKey32(requestId)); + } + + function _toRequestId(Key32 key) private pure returns (RequestId) { + return RequestIdLib.toRequestId(key.toKeyId()); + } } \ No newline at end of file diff --git a/contracts/instance/TargetNames.sol b/contracts/instance/TargetNames.sol index 37a28ab3d..845bd530d 100644 --- a/contracts/instance/TargetNames.sol +++ b/contracts/instance/TargetNames.sol @@ -7,4 +7,5 @@ string constant INSTANCE_STORE_TARGET_NAME = "InstanceStore"; string constant PRODUCT_STORE_TARGET_NAME = "ProductStore"; string constant BUNDLE_SET_TARGET_NAME = "BundleSet"; string constant RISK_SET_TARGET_NAME = "RiskSet"; +string constant REQUEST_SET_TARGET_NAME = "RequestSet"; diff --git a/contracts/oracle/IOracleService.sol b/contracts/oracle/IOracleService.sol index 96f04c28b..659780d30 100644 --- a/contracts/oracle/IOracleService.sol +++ b/contracts/oracle/IOracleService.sol @@ -63,4 +63,19 @@ interface IOracleService is IService { /// Permissioned: only the requester may cancel a request function cancel(RequestId requestId) external; + // FIXME: this should be done by request + function addRequest(RequestId requestId) external; + + // FIXME: this could be done by respond, resend, cancel + function removeRequest(RequestId requestId) external; + + // FIXME: move to instance reader + function activeRequests() external view returns(uint256 numberOfRequests); + + // FIXME: move to instance reader + function activeRequestAt(uint256 idx) external view returns(RequestId requestId); + + // FIXME: move to instance reader + function isActiveRequest(RequestId requestId) external view returns(bool isActive); + } \ No newline at end of file diff --git a/contracts/oracle/Oracle.sol b/contracts/oracle/Oracle.sol index a032a747d..030e12bf3 100644 --- a/contracts/oracle/Oracle.sol +++ b/contracts/oracle/Oracle.sol @@ -2,13 +2,12 @@ pragma solidity ^0.8.20; import {Amount} from "../type/Amount.sol"; -import {COMPONENT, PRODUCT, ORACLE} from "../type/ObjectType.sol"; +import {COMPONENT, ORACLE} from "../type/ObjectType.sol"; import {IAuthorization} from "../authorization/IAuthorization.sol"; import {IComponentService} from "../shared/IComponentService.sol"; import {IInstanceLinkedComponent} from "../shared/IInstanceLinkedComponent.sol"; import {IOracleComponent} from "./IOracleComponent.sol"; import {IOracleService} from "./IOracleService.sol"; -import {LibRequestIdSet} from "../type/RequestIdSet.sol"; import {NftId} from "../type/NftId.sol"; import {InstanceLinkedComponent} from "../shared/InstanceLinkedComponent.sol"; import {RequestId} from "../type/RequestId.sol"; @@ -23,10 +22,6 @@ abstract contract Oracle is // keccak256(abi.encode(uint256(keccak256("etherisc.storage.Oracle")) - 1)) & ~bytes32(uint256(0xff)); bytes32 public constant ORACLE_STORAGE_LOCATION_V1 = 0xaab7c0ea03d290e56d6c060e0733d3ebcbe647f7694616a2ec52738a64b2f900; - // TODO decide if this variable should be moved to instance store - // if so it need to manage active requests by requestor nft id - LibRequestIdSet.Set internal _activeRequests; - struct OracleStorage { IComponentService _componentService; IOracleService _oracleService; @@ -80,32 +75,32 @@ abstract contract Oracle is revert ErrorOracleNotImplemented("withdrawFees"); } - // TODO decide if the code below should be moved to GIF function activeRequests() external view returns(uint256 numberOfRequests) { - return LibRequestIdSet.size(_activeRequests); + OracleStorage storage $ = _getOracleStorage(); + return $._oracleService.activeRequests(); } - // TODO decide if the code below should be moved to GIF function getActiveRequest(uint256 idx) external view returns(RequestId requestId) { - return LibRequestIdSet.getElementAt(_activeRequests, idx); + OracleStorage storage $ = _getOracleStorage(); + return $._oracleService.activeRequestAt(idx); } - // TODO decide if the code below should be moved to GIF function isActiveRequest(RequestId requestId) external view returns(bool isActive) { - return LibRequestIdSet.contains(_activeRequests, requestId); + OracleStorage storage $ = _getOracleStorage(); + return $._oracleService.isActiveRequest(requestId); } function __Oracle_init( @@ -148,7 +143,6 @@ abstract contract Oracle is _getOracleStorage()._oracleService.respond(requestId, responseData); } - // TODO decide if the code below should be moved to GIF // check callback result function _updateRequestState( RequestId requestId @@ -157,10 +151,11 @@ abstract contract Oracle is { bool requestFulfilled = _getInstanceReader().getRequestState( requestId) == FULFILLED(); + OracleStorage storage $ = _getOracleStorage(); // remove from active requests when successful - if (requestFulfilled && LibRequestIdSet.contains(_activeRequests, requestId)) { - LibRequestIdSet.remove(_activeRequests, requestId); + if (requestFulfilled && $._oracleService.isActiveRequest(requestId)) { + $._oracleService.removeRequest(requestId); } } @@ -176,8 +171,8 @@ abstract contract Oracle is internal virtual { - // TODO decide if the line below should be moved to GIF - LibRequestIdSet.add(_activeRequests, requestId); + OracleStorage storage $ = _getOracleStorage(); + $._oracleService.addRequest(requestId); emit LogOracleRequestReceived(requestId, requesterId); } @@ -190,8 +185,8 @@ abstract contract Oracle is internal virtual { - // TODO decide if the line below should be moved to GIF - LibRequestIdSet.remove(_activeRequests, requestId); + OracleStorage storage $ = _getOracleStorage(); + $._oracleService.removeRequest(requestId); emit LogOracleRequestCancelled(requestId); } diff --git a/contracts/oracle/OracleService.sol b/contracts/oracle/OracleService.sol index 111f50312..6b9475e21 100644 --- a/contracts/oracle/OracleService.sol +++ b/contracts/oracle/OracleService.sol @@ -2,16 +2,14 @@ pragma solidity ^0.8.20; import {ContractLib} from "../shared/ContractLib.sol"; -import {IComponent} from "../shared/IComponent.sol"; import {IInstance} from "../instance/IInstance.sol"; -import {IInstanceService} from "../instance/IInstanceService.sol"; import {InstanceReader} from "../instance/InstanceReader.sol"; import {IOracle} from "./IOracle.sol"; import {IOracleComponent} from "./IOracleComponent.sol"; import {IOracleService} from "./IOracleService.sol"; import {IRegistry} from "../registry/IRegistry.sol"; import {NftId} from "../type/NftId.sol"; -import {ObjectType, COMPONENT, ORACLE, PRODUCT} from "../type/ObjectType.sol"; +import {ObjectType, ORACLE, PRODUCT} from "../type/ObjectType.sol"; import {RequestId} from "../type/RequestId.sol"; import {Service} from "../shared/Service.sol"; import {StateId, ACTIVE, KEEP_STATE, FULFILLED, FAILED, CANCELLED} from "../type/StateId.sol"; @@ -217,6 +215,84 @@ contract OracleService is emit LogOracleServiceRequestCancelled(requestId, requesterNftId); } + function activeRequests() + external + view + virtual + returns(uint256 numberOfRequests) + { + ( + IRegistry.ObjectInfo memory info, + address instanceAddress + ) = ContractLib.getAndVerifyAnyComponent( + getRegistry(), msg.sender, true); + IInstance instance = IInstance(instanceAddress); + + + return instance.getRequestSet().activeRequests(info.nftId); + } + + function activeRequestAt(uint256 idx) + external + view + virtual + returns(RequestId requestId) + { + ( + IRegistry.ObjectInfo memory info, + address instanceAddress + ) = ContractLib.getAndVerifyAnyComponent( + getRegistry(), msg.sender, true); + IInstance instance = IInstance(instanceAddress); + + return instance.getRequestSet().activeRequestAt(info.nftId, idx); + } + + function isActiveRequest(RequestId requestId) + external + view + virtual + returns(bool isActive) + { + ( + IRegistry.ObjectInfo memory info, + address instanceAddress + ) = ContractLib.getAndVerifyAnyComponent( + getRegistry(), msg.sender, true); + IInstance instance = IInstance(instanceAddress); + + return instance.getRequestSet().contains(info.nftId, requestId); + } + + function addRequest(RequestId requestId) + external + virtual + restricted() + { + ( + IRegistry.ObjectInfo memory info, + address instanceAddress + ) = ContractLib.getAndVerifyAnyComponent( + getRegistry(), msg.sender, true); + IInstance instance = IInstance(instanceAddress); + + instance.getRequestSet().add(info.nftId, requestId); + } + + function removeRequest(RequestId requestId) + external + virtual + restricted() + { + ( + IRegistry.ObjectInfo memory info, + address instanceAddress + ) = ContractLib.getAndVerifyAnyComponent( + getRegistry(), msg.sender, true); + IInstance instance = IInstance(instanceAddress); + + instance.getRequestSet().remove(info.nftId, requestId); + } function _checkRequestParams( IRegistry registry, diff --git a/contracts/registry/ServiceAuthorizationV3.sol b/contracts/registry/ServiceAuthorizationV3.sol index 896fa1fdb..15b6a7e3d 100644 --- a/contracts/registry/ServiceAuthorizationV3.sol +++ b/contracts/registry/ServiceAuthorizationV3.sol @@ -308,6 +308,8 @@ contract ServiceAuthorizationV3 _authorize(functions, IOracleService.respond.selector, "respond"); _authorize(functions, IOracleService.resend.selector, "resend"); _authorize(functions, IOracleService.cancel.selector, "cancel"); + _authorize(functions, IOracleService.addRequest.selector, "addRequest"); + _authorize(functions, IOracleService.removeRequest.selector, "removeRequest"); } function _setupApplicationServiceAuthorization() diff --git a/contracts/type/RequestId.sol b/contracts/type/RequestId.sol index 692361352..7f5f6d369 100644 --- a/contracts/type/RequestId.sol +++ b/contracts/type/RequestId.sol @@ -72,4 +72,10 @@ library RequestIdLib { function toKeyId(RequestId id) public pure returns (KeyId keyId) { return KeyId.wrap(bytes31(uint248(RequestId.unwrap(id)))); } + + function toRequestId(KeyId keyId) public pure returns (RequestId requestId) { + uint248 keyIdInt = uint248(bytes31(KeyId.unwrap(keyId))); + assert(keyIdInt < type(uint64).max); + return RequestId.wrap(uint64(keyIdInt)); + } } diff --git a/test/instance/authorization/InstanceAuthzRoles.t.sol b/test/instance/authorization/InstanceAuthzRoles.t.sol index b0b38f17d..93a859222 100644 --- a/test/instance/authorization/InstanceAuthzRoles.t.sol +++ b/test/instance/authorization/InstanceAuthzRoles.t.sol @@ -25,8 +25,8 @@ contract InstanceAuthzRolesTest is InstanceAuthzBaseTest { _printRoles(); // check initial roles - assertEq(instanceAdmin.roles(), 20, "unexpected initial instance roles count (admin)"); - assertEq(instanceReader.roles(), 20, "unexpected initial instance roles count (reader)"); + assertEq(instanceAdmin.roles(), 21, "unexpected initial instance roles count (admin)"); + assertEq(instanceReader.roles(), 21, "unexpected initial instance roles count (reader)"); } //--- role creation ----------------------------------------------------// diff --git a/test/instance/authorization/InstanceAuthzTargets.t.sol b/test/instance/authorization/InstanceAuthzTargets.t.sol index 778e87fef..1f707daa1 100644 --- a/test/instance/authorization/InstanceAuthzTargets.t.sol +++ b/test/instance/authorization/InstanceAuthzTargets.t.sol @@ -22,8 +22,8 @@ contract InstanceAuthzTargetsTest is InstanceAuthzBaseTest { _printTargets(); // check initial roles - assertEq(instanceAdmin.targets(), 6, "unexpected initial instance target count (admin)"); - assertEq(instanceReader.targets(), 6, "unexpected initial instance target count (reader)"); + assertEq(instanceAdmin.targets(), 7, "unexpected initial instance target count (admin)"); + assertEq(instanceReader.targets(), 7, "unexpected initial instance target count (reader)"); } From 3c65032b6716af38bf072b83661d3d55419e49b1 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 14:52:14 +0000 Subject: [PATCH 4/8] refactor: remove updateRequestState function and related logic from FlightOracle and IOracleService (#745) --- contracts/examples/flight/FlightOracle.sol | 12 ---- .../flight/FlightOracleAuthorization.sol | 5 +- contracts/oracle/IOracleService.sol | 6 -- contracts/oracle/Oracle.sol | 24 +------ contracts/oracle/OracleService.sol | 72 +++++++------------ contracts/registry/ServiceAuthorizationV3.sol | 2 - test/examples/flight/FlightProduct.t.sol | 24 +++---- 7 files changed, 36 insertions(+), 109 deletions(-) diff --git a/contracts/examples/flight/FlightOracle.sol b/contracts/examples/flight/FlightOracle.sol index cec74b78c..e5ef63ba8 100644 --- a/contracts/examples/flight/FlightOracle.sol +++ b/contracts/examples/flight/FlightOracle.sol @@ -95,18 +95,6 @@ contract FlightOracle is // effects + interaction (via framework to receiving component) _respond(requestId, responseData); - - _updateRequestState(requestId); - } - - - function updateRequestState( - RequestId requestId - ) - external - restricted() - { - _updateRequestState(requestId); } //--- view functions ----------------------------------------------------// diff --git a/contracts/examples/flight/FlightOracleAuthorization.sol b/contracts/examples/flight/FlightOracleAuthorization.sol index 26299b509..a418fd594 100644 --- a/contracts/examples/flight/FlightOracleAuthorization.sol +++ b/contracts/examples/flight/FlightOracleAuthorization.sol @@ -49,9 +49,8 @@ contract FlightOracleAuthorization functions = _authorizeForTarget(getMainTargetName(), STATUS_PROVIDER_ROLE); _authorize(functions, FlightOracle.respondWithFlightStatus.selector, "respondWithFlightStatus"); - // authorize public role (additional authz via onlyOwner) - functions = _authorizeForTarget(getMainTargetName(), PUBLIC_ROLE()); - _authorize(functions, FlightOracle.updateRequestState.selector, "updateRequestState"); + // // authorize public role (additional authz via onlyOwner) + // functions = _authorizeForTarget(getMainTargetName(), PUBLIC_ROLE()); } } diff --git a/contracts/oracle/IOracleService.sol b/contracts/oracle/IOracleService.sol index 659780d30..8c1fe4348 100644 --- a/contracts/oracle/IOracleService.sol +++ b/contracts/oracle/IOracleService.sol @@ -63,12 +63,6 @@ interface IOracleService is IService { /// Permissioned: only the requester may cancel a request function cancel(RequestId requestId) external; - // FIXME: this should be done by request - function addRequest(RequestId requestId) external; - - // FIXME: this could be done by respond, resend, cancel - function removeRequest(RequestId requestId) external; - // FIXME: move to instance reader function activeRequests() external view returns(uint256 numberOfRequests); diff --git a/contracts/oracle/Oracle.sol b/contracts/oracle/Oracle.sol index 030e12bf3..c64196939 100644 --- a/contracts/oracle/Oracle.sol +++ b/contracts/oracle/Oracle.sol @@ -11,7 +11,6 @@ import {IOracleService} from "./IOracleService.sol"; import {NftId} from "../type/NftId.sol"; import {InstanceLinkedComponent} from "../shared/InstanceLinkedComponent.sol"; import {RequestId} from "../type/RequestId.sol"; -import {FULFILLED} from "../type/StateId.sol"; import {Timestamp} from "../type/Timestamp.sol"; @@ -103,6 +102,7 @@ abstract contract Oracle is return $._oracleService.isActiveRequest(requestId); } + // solhint-disable-next-line func-name-mixedcase function __Oracle_init( address registry, NftId productNftId, @@ -143,23 +143,6 @@ abstract contract Oracle is _getOracleStorage()._oracleService.respond(requestId, responseData); } - // check callback result - function _updateRequestState( - RequestId requestId - ) - internal - { - bool requestFulfilled = _getInstanceReader().getRequestState( - requestId) == FULFILLED(); - OracleStorage storage $ = _getOracleStorage(); - - // remove from active requests when successful - if (requestFulfilled && $._oracleService.isActiveRequest(requestId)) { - $._oracleService.removeRequest(requestId); - } - } - - /// @dev use case specific handling of oracle requests /// for now only log is emitted to verify that request has been received by oracle component function _request( @@ -171,8 +154,6 @@ abstract contract Oracle is internal virtual { - OracleStorage storage $ = _getOracleStorage(); - $._oracleService.addRequest(requestId); emit LogOracleRequestReceived(requestId, requesterId); } @@ -185,13 +166,12 @@ abstract contract Oracle is internal virtual { - OracleStorage storage $ = _getOracleStorage(); - $._oracleService.removeRequest(requestId); emit LogOracleRequestCancelled(requestId); } function _getOracleStorage() private pure returns (OracleStorage storage $) { + // solhint-disable-next-line no-inline-assembly assembly { $.slot := ORACLE_STORAGE_LOCATION_V1 } diff --git a/contracts/oracle/OracleService.sol b/contracts/oracle/OracleService.sol index 6b9475e21..72fc3bcb6 100644 --- a/contracts/oracle/OracleService.sol +++ b/contracts/oracle/OracleService.sol @@ -54,7 +54,7 @@ contract OracleService is // get and check active caller ( IRegistry.ObjectInfo memory requesterInfo, - address instance + address instanceAddress ) = ContractLib.getAndVerifyAnyComponent( getRegistry(), msg.sender, true); @@ -67,7 +67,7 @@ contract OracleService is // effects { // create request info - IOracle.RequestInfo memory request = IOracle.RequestInfo({ + IOracle.RequestInfo memory requestInfo = IOracle.RequestInfo({ requesterNftId: requesterNftId, callbackMethodName: callbackMethodName, oracleNftId: oracleNftId, @@ -78,8 +78,9 @@ contract OracleService is isCancelled: false }); - // store request with instance - requestId = IInstance(instance).getInstanceStore().createRequest(request); + // store request with instance + requestId = IInstance(instanceAddress).getInstanceStore().createRequest(requestInfo); + IInstance(instanceAddress).getRequestSet().add(oracleNftId, requestId); } emit LogOracleServiceRequestCreated(requestId, requesterNftId, oracleNftId, expiryAt); @@ -114,22 +115,23 @@ contract OracleService is NftId oracleNftId = info.nftId; IInstance instance = IInstance(instanceAddress); bool callerIsOracle = true; - IOracle.RequestInfo memory request = _checkAndGetRequestInfo(instance, requestId, oracleNftId, callerIsOracle); - request.responseData = responseData; - request.respondedAt = TimestampLib.current(); + IOracle.RequestInfo memory requestInfo = _checkAndGetRequestInfo(instance, requestId, oracleNftId, callerIsOracle); + requestInfo.responseData = responseData; + requestInfo.respondedAt = TimestampLib.current(); instance.getInstanceStore().updateRequest( - requestId, request, KEEP_STATE()); + requestId, requestInfo, KEEP_STATE()); IRegistry.ObjectInfo memory requesterInfo = getRegistry().getObjectInfo( - request.requesterNftId); + requestInfo.requesterNftId); string memory functionSignature = string( abi.encodePacked( - request.callbackMethodName, + requestInfo.callbackMethodName, "(uint64,bytes)" )); + // solhint-disable-next-line avoid-low-level-calls (success, ) = requesterInfo.objectAddress.call( abi.encodeWithSignature( functionSignature, @@ -139,6 +141,7 @@ contract OracleService is // check that calling requestor was successful if (success) { instance.getInstanceStore().updateRequestState(requestId, FULFILLED()); + instance.getRequestSet().remove(oracleNftId, requestId); } else { instance.getInstanceStore().updateRequestState(requestId, FAILED()); emit LogOracleServiceDeliveryFailed(requestId, requesterInfo.objectAddress, functionSignature); @@ -162,24 +165,26 @@ contract OracleService is NftId requesterNftId = info.nftId; IInstance instance = IInstance(instanceAddress); bool callerIsOracle = false; - IOracle.RequestInfo memory request = _checkAndGetRequestInfo(instance, requestId, requesterNftId, callerIsOracle); + IOracle.RequestInfo memory requestInfo = _checkAndGetRequestInfo(instance, requestId, requesterNftId, callerIsOracle); // attempt to deliver response to requester string memory functionSignature = string( abi.encodePacked( - request.callbackMethodName, + requestInfo.callbackMethodName, "(uint64,bytes)" )); - (bool success, bytes memory returnData) = info.objectAddress.call( + // solhint-disable-next-line avoid-low-level-calls + (bool success, ) = info.objectAddress.call( abi.encodeWithSignature( functionSignature, requestId, - request.responseData)); + requestInfo.responseData)); // check that calling requestor was successful if (success) { instance.getInstanceStore().updateRequestState(requestId, FULFILLED()); + instance.getRequestSet().remove(requestInfo.oracleNftId, requestId); emit LogOracleServiceResponseResent(requestId, requesterNftId); } else { emit LogOracleServiceDeliveryFailed(requestId, info.objectAddress, functionSignature); @@ -202,14 +207,15 @@ contract OracleService is IInstance instance = IInstance(instanceAddress); bool callerIsOracle = false; // TODO property isCancelled and state update to CANCELLED are redundant, get rid of isCancelled - IOracle.RequestInfo memory request = _checkAndGetRequestInfo(instance, requestId, requesterNftId, callerIsOracle); - request.isCancelled = true; + IOracle.RequestInfo memory requestInfo = _checkAndGetRequestInfo(instance, requestId, requesterNftId, callerIsOracle); + requestInfo.isCancelled = true; - instance.getInstanceStore().updateRequest(requestId, request, CANCELLED()); + instance.getInstanceStore().updateRequest(requestId, requestInfo, CANCELLED()); + instance.getRequestSet().remove(requestInfo.oracleNftId, requestId); // call oracle component // TODO add check that oracle is active? - address oracleAddress = getRegistry().getObjectAddress(request.oracleNftId); + address oracleAddress = getRegistry().getObjectAddress(requestInfo.oracleNftId); IOracleComponent(oracleAddress).cancel(requestId); emit LogOracleServiceRequestCancelled(requestId, requesterNftId); @@ -264,36 +270,6 @@ contract OracleService is return instance.getRequestSet().contains(info.nftId, requestId); } - function addRequest(RequestId requestId) - external - virtual - restricted() - { - ( - IRegistry.ObjectInfo memory info, - address instanceAddress - ) = ContractLib.getAndVerifyAnyComponent( - getRegistry(), msg.sender, true); - IInstance instance = IInstance(instanceAddress); - - instance.getRequestSet().add(info.nftId, requestId); - } - - function removeRequest(RequestId requestId) - external - virtual - restricted() - { - ( - IRegistry.ObjectInfo memory info, - address instanceAddress - ) = ContractLib.getAndVerifyAnyComponent( - getRegistry(), msg.sender, true); - IInstance instance = IInstance(instanceAddress); - - instance.getRequestSet().remove(info.nftId, requestId); - } - function _checkRequestParams( IRegistry registry, NftId oracleNftId, diff --git a/contracts/registry/ServiceAuthorizationV3.sol b/contracts/registry/ServiceAuthorizationV3.sol index 15b6a7e3d..896fa1fdb 100644 --- a/contracts/registry/ServiceAuthorizationV3.sol +++ b/contracts/registry/ServiceAuthorizationV3.sol @@ -308,8 +308,6 @@ contract ServiceAuthorizationV3 _authorize(functions, IOracleService.respond.selector, "respond"); _authorize(functions, IOracleService.resend.selector, "resend"); _authorize(functions, IOracleService.cancel.selector, "cancel"); - _authorize(functions, IOracleService.addRequest.selector, "addRequest"); - _authorize(functions, IOracleService.removeRequest.selector, "removeRequest"); } function _setupApplicationServiceAuthorization() diff --git a/test/examples/flight/FlightProduct.t.sol b/test/examples/flight/FlightProduct.t.sol index 17360beef..fb4a23850 100644 --- a/test/examples/flight/FlightProduct.t.sol +++ b/test/examples/flight/FlightProduct.t.sol @@ -4,26 +4,23 @@ pragma solidity ^0.8.20; import {console} from "../../../lib/forge-std/src/Test.sol"; import {IAccess} from "../../../contracts/authorization/IAccess.sol"; -import {INftOwnable} from "../../../contracts/shared/INftOwnable.sol"; import {IOracle} from "../../../contracts/oracle/IOracle.sol"; import {IPolicy} from "../../../contracts/instance/module/IPolicy.sol"; -import {Amount, AmountLib} from "../../../contracts/type/Amount.sol"; -import {BUNDLE} from "../../../contracts/type/ObjectType.sol"; +import {Amount} from "../../../contracts/type/Amount.sol"; import {COLLATERALIZED, PAID} from "../../../contracts/type/StateId.sol"; import {FlightBaseTest} from "./FlightBase.t.sol"; import {FlightLib} from "../../../contracts/examples/flight/FlightLib.sol"; import {FlightNft} from "../../../contracts/examples/flight/FlightNft.sol"; import {FlightProduct} from "../../../contracts/examples/flight/FlightProduct.sol"; import {FlightOracle} from "../../../contracts/examples/flight/FlightOracle.sol"; -import {IBundle} from "../../../contracts/instance/module/IBundle.sol"; import {NftId} from "../../../contracts/type/NftId.sol"; import {RiskId} from "../../../contracts/type/RiskId.sol"; -import {RequestId, RequestIdLib} from "../../../contracts/type/RequestId.sol"; +import {RequestId} from "../../../contracts/type/RequestId.sol"; import {RoleId} from "../../../contracts/type/RoleId.sol"; import {Seconds, SecondsLib} from "../../../contracts/type/Seconds.sol"; import {StateId, ACTIVE, FAILED, FULFILLED} from "../../../contracts/type/StateId.sol"; -import {Str, StrLib} from "../../../contracts/type/String.sol"; +import {StrLib} from "../../../contracts/type/String.sol"; import {Timestamp, TimestampLib} from "../../../contracts/type/Timestamp.sol"; // solhint-disable func-name-mixedcase @@ -113,7 +110,9 @@ contract FlightProductTest is FlightBaseTest { vm.prank(instanceOwner); instance.authorizeFunctions(address(flightProduct), publicRoleId, functions); + // solhint-disable-next-line no-console console.log("setTestMode selector"); + // solhint-disable-next-line no-console console.logBytes4(FlightProduct.setTestMode.selector); // WHEN @@ -874,25 +873,18 @@ contract FlightProductTest is FlightBaseTest { vm.stopPrank(); // check intermediate state - assertEq(flightOracle.activeRequests(), 1, "unexpected number of active requests before updateRequestState"); - - // update request state -> will remove request from active requests if state is fulfilled - flightOracle.updateRequestState(requestId); - - // THEN - assertEq(flightOracle.activeRequests(), 0, "unexpected number of active requests after resend request"); + assertEq(flightOracle.activeRequests(), 0, "unexpected number of active requests before updateRequestState"); assertEq(instanceReader.getRequestState(requestId).toInt(), FULFILLED().toInt(), "request state not FAILED resend request"); policyInfo = instanceReader.getPolicyInfo(policyNftId); assertEq(policyInfo.claimsCount, 1, "unexpected number of claims (after resending request with sufficient wallet balance)"); assertEq(policyInfo.closedAt.toInt(), TimestampLib.current().toInt(), "unexpected closed at (after resending request with sufficient wallet balance)"); + // solhint-disable-next-line no-console console.log("--- state after pool funding and resending request ---"); + // solhint-disable-next-line no-console console.log("policy closed at", policyInfo.closedAt.toInt()); - // WHEN - check that function may be called more than once without reverts - flightOracle.updateRequestState(requestId); - requestInfo = instanceReader.getRequestInfo(requestId); _printRequest(requestId, requestInfo); From c1a42fb93d37b515884c8809f62ff2ffa3571008 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 15:00:37 +0000 Subject: [PATCH 5/8] refactor: move active requests read functions from IOracleService to InstanceReader (#745) --- contracts/instance/InstanceReader.sol | 15 ++++++++ contracts/oracle/IOracleService.sol | 9 ----- contracts/oracle/Oracle.sol | 9 ++--- contracts/oracle/OracleService.sol | 49 --------------------------- 4 files changed, 18 insertions(+), 64 deletions(-) diff --git a/contracts/instance/InstanceReader.sol b/contracts/instance/InstanceReader.sol index 86fd6af7b..b5dbad0f4 100644 --- a/contracts/instance/InstanceReader.sol +++ b/contracts/instance/InstanceReader.sol @@ -30,6 +30,7 @@ import {PolicyServiceLib} from "../product/PolicyServiceLib.sol"; import {ProductStore} from "./ProductStore.sol"; import {ReferralId, ReferralStatus, ReferralLib} from "../type/Referral.sol"; import {RequestId} from "../type/RequestId.sol"; +import {RequestSet} from "./RequestSet.sol"; import {RiskId} from "../type/RiskId.sol"; import {RiskSet} from "./RiskSet.sol"; import {RoleId, INSTANCE_OWNER_ROLE} from "../type/RoleId.sol"; @@ -56,6 +57,7 @@ contract InstanceReader { ProductStore internal _productStore; BundleSet internal _bundleSet; RiskSet internal _riskSet; + RequestSet internal _requestSet; IDistributionService internal _distributionService; /// @dev This initializer needs to be called from the instance itself. @@ -85,6 +87,7 @@ contract InstanceReader { _productStore = _instance.getProductStore(); _bundleSet = _instance.getBundleSet(); _riskSet = _instance.getRiskSet(); + _requestSet = _instance.getRequestSet(); _distributionService = IDistributionService(_registry.getServiceAddress(DISTRIBUTION(), _instance.getRelease())); } @@ -366,6 +369,18 @@ contract InstanceReader { return getState(requestId.toKey32()); } + function getActiveRequests(NftId oracleNftId) external view returns(uint256 numberOfRequests) { + return _requestSet.activeRequests(oracleNftId); + } + + function getActiveRequestAt(NftId oracleNftId, uint256 idx) external view returns(RequestId requestId) { + return _requestSet.activeRequestAt(oracleNftId, idx); + } + + function isRequestActive(NftId oracleNftId, RequestId requestId) external view returns(bool isActive) { + return _requestSet.contains(oracleNftId, requestId); + } + //--- pool functions -----------------------------------------------------------// /// @dev Returns the pool info for the given pool NFT ID. diff --git a/contracts/oracle/IOracleService.sol b/contracts/oracle/IOracleService.sol index 8c1fe4348..96f04c28b 100644 --- a/contracts/oracle/IOracleService.sol +++ b/contracts/oracle/IOracleService.sol @@ -63,13 +63,4 @@ interface IOracleService is IService { /// Permissioned: only the requester may cancel a request function cancel(RequestId requestId) external; - // FIXME: move to instance reader - function activeRequests() external view returns(uint256 numberOfRequests); - - // FIXME: move to instance reader - function activeRequestAt(uint256 idx) external view returns(RequestId requestId); - - // FIXME: move to instance reader - function isActiveRequest(RequestId requestId) external view returns(bool isActive); - } \ No newline at end of file diff --git a/contracts/oracle/Oracle.sol b/contracts/oracle/Oracle.sol index c64196939..35b30df1e 100644 --- a/contracts/oracle/Oracle.sol +++ b/contracts/oracle/Oracle.sol @@ -79,8 +79,7 @@ abstract contract Oracle is view returns(uint256 numberOfRequests) { - OracleStorage storage $ = _getOracleStorage(); - return $._oracleService.activeRequests(); + return _getInstanceReader().getActiveRequests(getNftId()); } @@ -89,8 +88,7 @@ abstract contract Oracle is view returns(RequestId requestId) { - OracleStorage storage $ = _getOracleStorage(); - return $._oracleService.activeRequestAt(idx); + return _getInstanceReader().getActiveRequestAt(getNftId(), idx); } function isActiveRequest(RequestId requestId) @@ -98,8 +96,7 @@ abstract contract Oracle is view returns(bool isActive) { - OracleStorage storage $ = _getOracleStorage(); - return $._oracleService.isActiveRequest(requestId); + return _getInstanceReader().isRequestActive(getNftId(), requestId); } // solhint-disable-next-line func-name-mixedcase diff --git a/contracts/oracle/OracleService.sol b/contracts/oracle/OracleService.sol index 72fc3bcb6..5422ed6b0 100644 --- a/contracts/oracle/OracleService.sol +++ b/contracts/oracle/OracleService.sol @@ -221,55 +221,6 @@ contract OracleService is emit LogOracleServiceRequestCancelled(requestId, requesterNftId); } - function activeRequests() - external - view - virtual - returns(uint256 numberOfRequests) - { - ( - IRegistry.ObjectInfo memory info, - address instanceAddress - ) = ContractLib.getAndVerifyAnyComponent( - getRegistry(), msg.sender, true); - IInstance instance = IInstance(instanceAddress); - - - return instance.getRequestSet().activeRequests(info.nftId); - } - - function activeRequestAt(uint256 idx) - external - view - virtual - returns(RequestId requestId) - { - ( - IRegistry.ObjectInfo memory info, - address instanceAddress - ) = ContractLib.getAndVerifyAnyComponent( - getRegistry(), msg.sender, true); - IInstance instance = IInstance(instanceAddress); - - return instance.getRequestSet().activeRequestAt(info.nftId, idx); - } - - function isActiveRequest(RequestId requestId) - external - view - virtual - returns(bool isActive) - { - ( - IRegistry.ObjectInfo memory info, - address instanceAddress - ) = ContractLib.getAndVerifyAnyComponent( - getRegistry(), msg.sender, true); - IInstance instance = IInstance(instanceAddress); - - return instance.getRequestSet().contains(info.nftId, requestId); - } - function _checkRequestParams( IRegistry registry, NftId oracleNftId, From f80e4aabfda05afdb17f4b4f32af3a72d45e8923 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 15:13:15 +0000 Subject: [PATCH 6/8] add master instance request set deployment in deployAndRegisterMasterInstance (#745) --- scripts/libs/instance.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/libs/instance.ts b/scripts/libs/instance.ts index 7081f52b7..b0bad1c42 100644 --- a/scripts/libs/instance.ts +++ b/scripts/libs/instance.ts @@ -162,6 +162,21 @@ export async function deployAndRegisterMasterInstance( ); const masterInstanceRiskSet = masterRiskSetContrat as RiskSet; + const {address: masterInstanceRequestSetAddress, contract: masterRequestSetContrat} = await deployContract( + "RequestSet", + owner, + [], + { + libraries: { + Key32Lib: libraries.key32LibAddress, + LibKey32Set: libraries.libKey32SetAddress, + ObjectSetHelperLib: libraries.objectSetHelperLibAddress, + RequestIdLib: libraries.requestIdLibAddress, + } + } + ); + const masterInstanceRequestSet = masterRequestSetContrat as RiskSet; + const { address: masterInstanceReaderAddress, contract: masterInstanceReaderContract } = await deployContract( "InstanceReader", owner, @@ -200,17 +215,13 @@ export async function deployAndRegisterMasterInstance( await executeTx( () => masterInstance.initialize( - // masterInstanceAdmin, - // masterInstanceStore, - // masterInstanceBundleSet, - // masterInstanceRiskSet, - // masterInstanceReader, { instanceAdmin: masterInstanceAdminAddress, instanceStore: masterInstanceStoreAddress, productStore: masterProductStoreAddress, bundleSet: masterInstanceBundleSetAddress, riskSet: masterInstanceRiskSetAddress, + requestSet: masterInstanceRequestSetAddress, instanceReader: masterInstanceReaderAddress }, registry.registryAddress, From 432feaf196af54144180f8701026fa0fe1148243 Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 15:16:52 +0000 Subject: [PATCH 7/8] refactor: remove LibRequestIdSet from deployFlightDelayComponentContracts (#745) --- scripts/deploy_flightdelay_components.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/deploy_flightdelay_components.ts b/scripts/deploy_flightdelay_components.ts index 8fe8299a4..d40062060 100644 --- a/scripts/deploy_flightdelay_components.ts +++ b/scripts/deploy_flightdelay_components.ts @@ -320,7 +320,6 @@ export async function deployFlightDelayComponentContracts(libraries: LibraryAddr libraries: { ContractLib: contractLibAddress, NftIdLib: nftIdLibAddress, - LibRequestIdSet: libRequestIdSetAddress, StrLib: strLibAddress, TimestampLib: timestampLibAddress, VersionLib: versionLibAddress, From 125789ef91f1e4e4911c059df5c959d44bbc389e Mon Sep 17 00:00:00 2001 From: Marc Doerflinger Date: Fri, 13 Dec 2024 15:24:28 +0000 Subject: [PATCH 8/8] cleanup --- contracts/examples/flight/FlightOracle.sol | 2 +- contracts/oracle/Oracle.sol | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/examples/flight/FlightOracle.sol b/contracts/examples/flight/FlightOracle.sol index e5ef63ba8..73792be0e 100644 --- a/contracts/examples/flight/FlightOracle.sol +++ b/contracts/examples/flight/FlightOracle.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.20; import {IAuthorization} from "../../authorization/IAuthorization.sol"; -import {ACTIVE, FULFILLED, FAILED} from "../../type/StateId.sol"; +import {ACTIVE, FAILED} from "../../type/StateId.sol"; import {NftId} from "../../type/NftId.sol"; import {BasicOracle} from "../../oracle/BasicOracle.sol"; import {RequestId} from "../../type/RequestId.sol"; diff --git a/contracts/oracle/Oracle.sol b/contracts/oracle/Oracle.sol index 35b30df1e..ca5e06408 100644 --- a/contracts/oracle/Oracle.sol +++ b/contracts/oracle/Oracle.sol @@ -63,7 +63,7 @@ abstract contract Oracle is } /// @dev Not relevant for oracle components - function withdrawFees(Amount amount) + function withdrawFees(Amount) external virtual override(IInstanceLinkedComponent, InstanceLinkedComponent) @@ -145,8 +145,8 @@ abstract contract Oracle is function _request( RequestId requestId, NftId requesterId, - bytes calldata requestData, - Timestamp expiryAt + bytes calldata, + Timestamp ) internal virtual