Skip to content

Commit

Permalink
Unify terminology on providers
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiimk committed Apr 30, 2024
1 parent cd9f325 commit e5ba986
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 63 deletions.
2 changes: 1 addition & 1 deletion .env.local
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ ETH_FROM="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
ORACLE_CONTRACT_ADDR="0x5FbDB2315678afecb367f032d93F642f64180aa3"
CONSUMER_CONTRACT_ADDR="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
EXECUTOR_ADDR="0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
PROVIDER_ADDR="0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
4 changes: 2 additions & 2 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ npm run deploy:local
See also:

```sh
# Send transaction to authorize local executor
npm run send:add-executor:local
# Send transaction to authorize local provider
npm run send:add-provider:local

# Trigger oracle request transaction from the test consumer contract
npm run send:oracle:local
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"test:coverage:report": "forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage",
"deploy:local": "export $(cat .env.local | xargs) && forge script script/Deploy.s.sol --fork-url http://localhost:8545 --private-key $PRIVATE_KEY --broadcast",
"deploy:sepolia": "export $(cat .env.test.sepolia | xargs) && forge script script/Deploy.s.sol -vvvv --rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcast --verify",
"send:add-executor:local": "export $(cat .env.local | xargs) && cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $ORACLE_CONTRACT_ADDR 'addExecutor(address)' $EXECUTOR_ADDR",
"send:add-executor:sepolia": "export $(cat .env.test.sepolia | xargs) && cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $ORACLE_CONTRACT_ADDR 'addExecutor(address)' $EXECUTOR_ADDR",
"send:add-provider:local": "export $(cat .env.local | xargs) && cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $ORACLE_CONTRACT_ADDR 'addProvider(address)' $PROVIDER_ADDR",
"send:add-provider:sepolia": "export $(cat .env.test.sepolia | xargs) && cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $ORACLE_CONTRACT_ADDR 'addProvider(address)' $PROVIDER_ADDR",
"send:oracle:local": "export $(cat .env.local | xargs) && cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $CONSUMER_CONTRACT_ADDR 'startDistributeRewards()'",
"send:oracle:sepolia": "export $(cat .env.test.sepolia | xargs) && cast send --rpc-url $RPC_URL --private-key $PRIVATE_KEY $CONSUMER_CONTRACT_ADDR 'startDistributeRewards()'",
"call:consumer-state:local": "export $(cat .env.local | xargs) && cast call --rpc-url $RPC_URL $CONSUMER_CONTRACT_ADDR 'province() returns(string)' && cast call --rpc-url $RPC_URL $CONSUMER_CONTRACT_ADDR 'totalCases() returns(uint64)'"
Expand Down
26 changes: 13 additions & 13 deletions src/Odf.sol
Original file line number Diff line number Diff line change
Expand Up @@ -113,23 +113,23 @@ interface IOdfClient {

////////////////////////////////////////////////////////////////////////////////////////

// Interface used by executors
// Interface used by data providers
interface IOdfProvider {
// Emitted when client request was made and awaits a response
event SendRequest(uint64 indexed requestId, address indexed consumerAddr, bytes request);

// Emitted when an executor fulfills a pending request
// Emitted when a provider fulfills a pending request
event ProvideResult(
uint64 indexed requestId,
address indexed consumerAddr,
address indexed executorAddr,
address indexed providerAddr,
bytes result,
bool consumerError,
bytes consumerErrorData
);

// Returned when executor was not registered to provide results to the oracle
error UnauthorizedExecutor(address executorAddr);
// Returned when provider was not registered to provide results to the oracle
error UnauthorizedProvider(address providerAddr);

// Returned when pending request by this ID is not found
error RequestNotFound(uint64 requestId);
Expand All @@ -146,15 +146,15 @@ interface IOdfProvider {

// Interface used by oracle admins
interface IOdfAdmin {
// Emitted when executor is authorized
event AddExecutor(address indexed executorAddr);
// Emitted when a provider is authorized
event AddProvider(address indexed providerAddr);

// Emitted when executor authorization is revoked
event RemoveExecutor(address indexed executorAddr);
// Emitted when a provider authorization is revoked
event RemoveProvider(address indexed providerAddr);

// Register an authorized executor
function addExecutor(address _addr) external;
// Authorizes a provider to supply results
function addProvider(address providerAddr) external;

// Revoke the authorization from an executor to supply results
function removeExecutor(address _addr) external;
// Revoke the authorization from a provider to supply results
function removeProvider(address providerAddr) external;
}
64 changes: 29 additions & 35 deletions src/OdfOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,24 @@ contract OdfOracle is IOdfClient, IOdfProvider, IOdfAdmin, Ownable {
function(OdfResponse.Res memory) external callback;
}

struct ExecutorInfo {
address addr;
struct ProviderInfo {
address providerAddr;
}

bool private immutable LOG_CONSUMER_ERROR_DATA;
uint64 private lastRequestId = 0;
uint64 private sLastRequestId = 0;

mapping(address executorAddress => ExecutorInfo executorInfo) private executors;
mapping(uint64 requestId => PendingRequest pendingRequest) private requests;
mapping(address providerAddress => ProviderInfo providerInfo) private sProviders;
mapping(uint64 requestId => PendingRequest pendingRequest) private sRequests;

constructor(bool logConsumerErrorData) Ownable(msg.sender) {
LOG_CONSUMER_ERROR_DATA = logConsumerErrorData;
}

modifier onlyAuthorizedExecutor() {
if (executors[msg.sender].addr == address(0)) revert UnauthorizedExecutor(msg.sender);
modifier onlyAuthorizedProvider() {
if (sProviders[msg.sender].providerAddr != msg.sender) {
revert UnauthorizedProvider(msg.sender);
}
_;
}

Expand All @@ -45,61 +47,53 @@ contract OdfOracle is IOdfClient, IOdfProvider, IOdfAdmin, Ownable {
external
returns (uint64)
{
lastRequestId += 1;
requests[lastRequestId] = PendingRequest(lastRequestId, _callback);
sLastRequestId += 1;
sRequests[sLastRequestId] = PendingRequest(sLastRequestId, _callback);

bytes memory requestData = _request.intoBytes();
emit SendRequest(lastRequestId, _callback.address, requestData);
emit SendRequest(sLastRequestId, _callback.address, requestData);

return lastRequestId;
return sLastRequestId;
}

// IOdfProvider

function canProvideResults(address _addr) external view returns (bool) {
return executors[_addr].addr != address(0);
function canProvideResults(address providerAddr) external view returns (bool) {
return sProviders[providerAddr].providerAddr == providerAddr;
}

function provideResult(
uint64 _requestId,
bytes memory _result
)
external
onlyAuthorizedExecutor
{
PendingRequest memory req = requests[_requestId];
if (req.requestId != _requestId) {
revert RequestNotFound(_requestId);
function provideResult(uint64 requestId, bytes memory result) external onlyAuthorizedProvider {
PendingRequest memory req = sRequests[requestId];
if (req.requestId != requestId) {
revert RequestNotFound(requestId);
}
delete requests[_requestId];
delete sRequests[requestId];

OdfResponse.Res memory res = OdfResponse.fromBytes(_requestId, _result);
OdfResponse.Res memory res = OdfResponse.fromBytes(requestId, result);

// TODO: Trap errors, as failure of a consumer contract doesn't mean that the oracle failed
// to provide a valid result
try req.callback(res) {
emit ProvideResult(_requestId, req.callback.address, msg.sender, _result, false, "");
emit ProvideResult(requestId, req.callback.address, msg.sender, result, false, "");
} catch (bytes memory consumerErrorData) {
if (!LOG_CONSUMER_ERROR_DATA) {
consumerErrorData = "";
}
emit ProvideResult(
_requestId, req.callback.address, msg.sender, _result, true, consumerErrorData
requestId, req.callback.address, msg.sender, result, true, consumerErrorData
);
}
}

// IOdfAdmin

// Register an authorized executor
function addExecutor(address _addr) external onlyOwner {
executors[_addr] = ExecutorInfo(_addr);
emit AddExecutor(_addr);
function addProvider(address providerAddr) external onlyOwner {
sProviders[providerAddr] = ProviderInfo(providerAddr);
emit AddProvider(providerAddr);
}

// Revoke the authorization from an executor to supply results
function removeExecutor(address _addr) external onlyOwner {
delete executors[_addr];
emit RemoveExecutor(_addr);
function removeProvider(address providerAddr) external onlyOwner {
delete sProviders[providerAddr];
emit RemoveProvider(providerAddr);
}
}
20 changes: 10 additions & 10 deletions test/OdfOracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,38 @@ contract OdfOracleTest is Test {
oracle = new OdfOracle({ logConsumerErrorData: false });
}

function testOwnerCanAddExecutor() public {
function testOwnerCanAddProvider() public {
vm.expectEmit(true, true, true, true);
emit IOdfAdmin.AddExecutor(address(0x123));
emit IOdfAdmin.AddProvider(address(0x123));

oracle.addExecutor(address(0x123));
oracle.addProvider(address(0x123));
}

function testNonOwnerCantAddExecutor() public {
function testNonOwnerCantAddProvider() public {
vm.expectRevert(
abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(0x1))
);
vm.prank(address(0x1));
oracle.addExecutor(address(0x123));
oracle.addProvider(address(0x123));
}

function testProvideResultUnauthorizedExecutor() public {
function testProvideResultUnauthorizedProvider() public {
vm.expectRevert(
abi.encodeWithSelector(IOdfProvider.UnauthorizedExecutor.selector, address(this))
abi.encodeWithSelector(IOdfProvider.UnauthorizedProvider.selector, address(this))
);
// CBOR: {"data": []}
oracle.provideResult(1, hex"A1646461746180");
}

function testProvideResultRequestNotFound() public {
oracle.addExecutor(address(this));
oracle.addProvider(address(this));
vm.expectRevert(abi.encodeWithSelector(IOdfProvider.RequestNotFound.selector, 1));
// CBOR: {"data": []}
oracle.provideResult(1, hex"A1646461746180");
}

function testProvideResultSuccess() public {
oracle.addExecutor(address(this));
oracle.addProvider(address(this));

HappyConsumer consumer = new HappyConsumer(address(oracle));

Expand All @@ -68,7 +68,7 @@ contract OdfOracleTest is Test {
}

function commonProvideResultConsumerSideError(ConsumerBase consumer) public {
oracle.addExecutor(address(this));
oracle.addProvider(address(this));

consumer.makeReuqest();

Expand Down

0 comments on commit e5ba986

Please sign in to comment.