add: DioneOracle contract to replace Aggregator and OracleEmitter with simple oracle requests storage

This commit is contained in:
bahadylbekov 2020-11-30 03:22:18 +03:00
parent e55c19a38d
commit b4c03da4ba
4 changed files with 1115 additions and 25 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,104 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.12;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/DioneStakingInterface.sol";
contract DioneOracle is Ownable {
using SafeMath for uint256;
uint256 private requestCounter;
uint256 constant public MAXIMUM_DELAY = 5 minutes;
DioneStakingInterface public dioneStaking;
struct OracleRequest {
uint8 originChain; // origin blockchain for request
string requestType; // rpc call type
string requestParams; // rpc call params
address callbackAddress; // callback address for users request contract
bytes4 callbackMethodID; // method for users request contract
uint256 reqID; // request counter
uint256 deadline;
bytes data;
}
mapping(uint256 => bytes32) private pendingRequests;
mapping(address => bool) private activeNodes;
event NewOracleRequest(
uint8 originChain,
string requestType,
string requestParams,
address callbackAddress,
bytes4 callbackMethodID,
uint256 reqID,
uint256 deadline
);
event CancelOracleRequest(
uint256 reqID
);
event SubmittedOracleRequest(
string requestParams,
address callbackAddress,
bytes4 callbackMethodID,
uint256 reqID,
uint256 deadline,
bytes data
);
modifier onlyPendingRequest(uint256 _reqID) {
require(pendingRequests[_reqID] != 0, "Invalid requestId");
_;
}
modifier onlyActiveNode() {
require(activeNodes[msg.sender], "Not an active miner");
_;
}
constructor(DioneStakingInterface _dioneStaking) public {
dioneStaking = _dioneStaking;
}
function requestOracles(uint8 _originChain, string memory _requestType, string memory _requestParams, address _callbackAddress, bytes4 _callbackMethodID) public returns (uint256) {
requestCounter += 1;
require(pendingRequests[requestCounter] == 0, "This counter is not unique");
uint256 requestDeadline = now.add(MAXIMUM_DELAY);
pendingRequests[requestCounter] = keccak256(abi.encodePacked(_requestParams, _callbackAddress, _callbackMethodID, requestCounter, requestDeadline));
emit NewOracleRequest(_originChain, _requestType, _requestParams, _callbackAddress, _callbackMethodID, requestCounter, requestDeadline);
return requestCounter;
}
function cancelOracleRequest(string memory _requestParams, bytes4 _callbackMethodID, uint256 _reqID, uint256 _requestDeadline) public {
bytes32 requestHash = keccak256(abi.encodePacked(_requestParams, msg.sender, _callbackMethodID, _reqID, _requestDeadline));
require(requestHash == pendingRequests[_reqID], "Request hash do not match it's origin");
require(_requestDeadline <= now, "Request didn't reached it's deadline");
delete pendingRequests[_reqID];
emit CancelOracleRequest(_reqID);
}
function submitOracleRequest(string memory _requestParams, address _callbackAddress, bytes4 _callbackMethodID, uint256 _reqID, uint256 _requestDeadline, bytes memory _data) public onlyActiveNode returns (bool) {
bytes32 requestHash = keccak256(abi.encodePacked(_requestParams, _callbackAddress, _callbackMethodID, _reqID, _requestDeadline));
require(pendingRequests[_reqID] == requestHash, "Params do not match request ID");
delete pendingRequests[_reqID];
dioneStaking.mine(msg.sender);
(bool success, ) = _callbackAddress.call(abi.encodeWithSelector(_callbackMethodID, _reqID, _data));
emit SubmittedOracleRequest(_requestParams, _callbackAddress, _callbackMethodID, _reqID, _requestDeadline, _data);
return success;
}
function setNodeStatus(address _miner, bool _status) public {
activeNodes[_miner] = _status;
}
function isActiveNode(address _miner) public view returns (bool) {
return activeNodes[_miner];
}
}

View File

@ -0,0 +1,14 @@
pragma solidity ^0.6.0;
interface DioneStakingInterface {
function mine(address _minerAddr) external;
function mineAndStake(address _minerAddr) external;
function stake(uint256 _amount) external;
function withdraw(uint256 _amount) external;
function totalStake() external view returns (uint256);
function minerStake(address _minerAddr) external view returns (uint256);
function setMinerReward(uint256 _minerReward) external;
function isMiner(address _minerAddr) external view returns (bool);
function setMinimumStake(uint256 _minimumStake) external;
function setAggregator(address _aggregatorAddr) external;
}

View File

@ -23,6 +23,7 @@ type EthereumClient struct {
oracleEmitter *oracleEmitter.OracleEmitterSession
aggregator *aggregator.AggregatorSession
dioneStaking *stakingContract.DioneStakingSession
// dioneOracle *dioneOracle.DioneOracleSession
}
type OracleEvent struct {
@ -71,6 +72,10 @@ func (c *EthereumClient) Initialize(ctx context.Context, url, privateKey, oracle
if err != nil {
return err
}
// oracleContract, err := dioneOracle.NewDioneOracle(common.HexToAddress(dioneOracleContract), client)
// if err != nil {
// return err
// }
c.oracleEmitter = &oracleEmitter.OracleEmitterSession{
Contract: emitter,
CallOpts: bind.CallOpts{
@ -116,6 +121,21 @@ func (c *EthereumClient) Initialize(ctx context.Context, url, privateKey, oracle
Context: context.Background(),
},
}
// c.dioneOracle = &dioneOracle.DioneOracleSession{
// Contract: oracleContract,
// CallOpts: bind.CallOpts{
// Pending: true,
// From: authTransactor.From,
// Context: context.Background(),
// },
// TransactOpts: bind.TransactOpts{
// From: authTransactor.From,
// Signer: authTransactor.Signer,
// GasLimit: 200000, // 0 automatically estimates gas limit
// GasPrice: big.NewInt(1860127603), // nil automatically suggests gas price
// Context: context.Background(),
// },
// }
return nil
}
@ -136,32 +156,20 @@ func (c *EthereumClient) SubscribeOnOracleEvents(ctx context.Context) (chan *ora
return resChan, subscription, err
}
// func (c *EthereumClient) SubscribeOnSumbittedRequests(ctx context.Context) (chan *dioneOracle.DioneOracleSubmittedOracleRequest, event.Subscription, error) {
// resChan := make(chan *dioneOracle.DioneOracleSubmittedOracleRequest)
// requestsFilter := c.dioneOracle.Contract.DioneOracleFilterer
// subscription, err := requestsFilter.WatchSubmittedOracleRequest(&bind.WatchOpts{
// Start: nil, //last block
// Context: ctx,
// }, resChan)
// if err != nil {
// return nil, nil, err
// }
// return resChan, subscription, err
// }
func (c *EthereumClient) SubmitRequestAnswer(reqID *big.Int, data string, callbackAddress common.Address) error {
// privateKey, err := crypto.HexToECDSA(private_key)
// if err != nil {
// c.Logger.Fatal("Failed to generate private key", err)
// }
// publicKey := privateKey.Public()
// publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
// if !ok {
// c.Logger.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
// }
// publicKeyBytes := crypto.FromECDSAPub(publicKeyECDSA)
// c.Logger.Info(hexutil.Encode(publicKeyBytes)[4:])
// fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
// nonce, err := c.HttpClient.PendingNonceAt(ctx, fromAddress)
// if err != nil {
// c.Logger.Fatal(err)
// }
// gasPrice, err := c.HttpClient.SuggestGasPrice(ctx)
// if err != nil {
// c.Logger.Fatal(err)
// }
_, err := c.aggregator.CollectData(reqID, data, callbackAddress)
if err != nil {
return err