Skip to content

Commit

Permalink
Merge pull request #38 from primevprotocol/ckaritk/oracle-continued-work
Browse files Browse the repository at this point in the history
Completes Oracle + Testing
  • Loading branch information
ckartik authored Nov 10, 2023
2 parents a6f6d3d + d3a15f0 commit 855a1db
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 51 deletions.
33 changes: 31 additions & 2 deletions contracts/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {IPreConfCommitmentStore} from './interfaces/IPreConfirmations.sol';
*/
contract Oracle is Ownable {

mapping(string => address) public blockBuilderNameToAddress;

// To shutup the compiler
// TODO(@ckartik): remove or make Oracle non-payable
receive() external payable {
Expand All @@ -39,20 +41,29 @@ contract Oracle is Ownable {
preConfContract = IPreConfCommitmentStore(_preConfContract);
}

// mapping of txns to bool to check if txns exists
// Stores all proccessed txns for onw
// TODO(@ckartik): This may be too restricvie in the log run as an appraoch
mapping(string => bool) txnHashes;


// Event to request block data
event BlockDataRequested(uint256 blockNumber);

// Event to signal the reception of block data
event BlockDataReceived(
bytes32[] txnList,
string[] txnList,
uint256 blockNumber,
string blockBuilderName
);

// Event to signal the processing of a commitment
event CommitmentProcessed(bytes32 commitmentHash, bool isSlash);

function addBuilderAddress(string memory builderName, address builderAddress) external onlyOwner {
blockBuilderNameToAddress[builderName] = builderAddress;
}

// Function to request the block data
function requestBlockData(uint256 blockNumber) external {
// Emit an event that data request has been made
Expand All @@ -62,14 +73,32 @@ contract Oracle is Ownable {
// Function to receive and process the block data (this would be automated in a real-world scenario)
// TODO(@ckartik): Should restrict who can make this call
function receiveBlockData(
bytes32[] calldata txnList,
string[] calldata txnList,
uint256 blockNumber,
string calldata blockBuilderName
) external {
// Emit an event that the block data has been received
emit BlockDataReceived(txnList, blockNumber, blockBuilderName);
address builder = blockBuilderNameToAddress[blockBuilderName];

for (uint256 i = 0; i < txnList.length; i++) {
txnHashes[txnList[i]] = true;
}

// Placeholder: Process the block data and determine the commitment's validity
// For demonstration, we'll call this with a dummy commitment hash and isSlash flag
bytes32[] memory commitmentHashes = preConfContract.getCommitmentsByBlockNumber(blockNumber);
for (uint256 i = 0; i < commitmentHashes.length; i++) {
IPreConfCommitmentStore.PreConfCommitment memory commitment = preConfContract.getCommitment(commitmentHashes[i]);
if (commitment.commiter == builder) {
if (txnHashes[commitment.txnHash]){
this.processCommitment(commitmentHashes[i], false);
}
else {
this.processCommitment(commitmentHashes[i], true);
}
}
}
}

// Function to simulate the processing of a commitment (initiate a slash or a reward)
Expand Down
27 changes: 19 additions & 8 deletions contracts/PreConfirmations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ contract PreConfCommitmentStore is Ownable {
uint64 blockNumber;
bytes32 bidHash;
string txnHash;
string commitmentHash;
bytes32 commitmentHash;
bytes bidSignature;
bytes commitmentSignature;
}
Expand Down Expand Up @@ -272,7 +272,6 @@ contract PreConfCommitmentStore is Ownable {
* @param bid The bid amount.
* @param blockNumber The block number.
* @param txnHash The transaction hash.
* @param commitmentHash The commitment hash.
* @param bidSignature The signature of the bid.
* @param commitmentSignature The signature of the commitment.
* @return commitmentIndex The index of the stored commitment
Expand All @@ -281,7 +280,6 @@ contract PreConfCommitmentStore is Ownable {
uint64 bid,
uint64 blockNumber,
string memory txnHash,
string memory commitmentHash,
bytes calldata bidSignature,
bytes memory commitmentSignature
) public returns (bytes32 commitmentIndex) {
Expand Down Expand Up @@ -313,7 +311,7 @@ contract PreConfCommitmentStore is Ownable {
blockNumber,
bHash,
txnHash,
commitmentHash,
preConfHash,
bidSignature,
commitmentSignature
);
Expand Down Expand Up @@ -349,15 +347,28 @@ contract PreConfCommitmentStore is Ownable {
}


/**
* @dev Retrieves the list of commitments for a given block number.
* @param blockNumber The block number.
* @return A list of indexes referencing preconfimration structures for the specified block number.
*/
function getCommitmentsByBlockNumber(uint256 blockNumber)
public
view
returns (bytes32[] memory)
{
return blockCommitments[blockNumber];
}

/**
* @dev Get a commitment by its hash.
* @param commitmentHash The hash of the commitment.
* @dev Get a commitment by its commitmentIndex.
* @param commitmentIndex The index of the commitment.
* @return A PreConfCommitment structure representing the commitment.
*/
function getCommitment(
bytes32 commitmentHash
bytes32 commitmentIndex
) public view returns (PreConfCommitment memory) {
return commitments[commitmentHash];
return commitments[commitmentIndex];
}

/**
Expand Down
7 changes: 7 additions & 0 deletions contracts/UserRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ contract UserRegistry is IUserRegistry, Ownable, ReentrancyGuard {
preConfirmationsContract = contractAddress;
}

/**
* @dev Get the amount assigned to a provider.
*/
function getProviderAmount(address provider) external view returns (uint256) {
return providerAmount[provider];
}

/**
* @dev Internal function for user registration and staking.
*/
Expand Down
13 changes: 9 additions & 4 deletions contracts/interfaces/IPreConfirmations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pragma solidity ^0.8.20;
interface IPreConfCommitmentStore {
// Structs, events, and errors can also be included in the interface if they are used in the external functions

/// @dev Struct for all the information around preconfirmations commitment
struct PreConfCommitment {
bool commitmentUsed;
address bidder;
Expand All @@ -16,11 +17,12 @@ interface IPreConfCommitmentStore {
uint64 blockNumber;
bytes32 bidHash;
string txnHash;
string commitmentHash;
bytes32 commitmentHash;
bytes bidSignature;
bytes commitmentSignature;
}


event SignatureVerified(
address indexed signer,
string txnHash,
Expand Down Expand Up @@ -64,11 +66,14 @@ interface IPreConfCommitmentStore {
bytes memory commitmentSignature
) external returns (uint256);

function getCommitment(bytes32 commitmentHash) external view returns (PreConfCommitment memory);
function getCommitmentsByBlockNumber(uint256 blockNumber) external view returns (bytes32[] memory);


function getCommitment(bytes32 commitmentIndex) external view returns (PreConfCommitment memory);

function initiateSlash(bytes32 commitmentHash) external;
function initiateSlash(bytes32 commitmentIndex) external;

function initateReward(bytes32 commitmentHash) external;
function initateReward(bytes32 commitmentIndex) external;

function updateOracle(address newOracle) external;

Expand Down
9 changes: 5 additions & 4 deletions hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ module.exports = {
localhost: {
url: "http://127.0.0.1:8545", // Ganache default port
},
hardhat: {},
op_docker: {
url: "http://op-geth:8545",
},
aws: {
url: "http://34.213.237.94:8123",
chainId: 1001,
accounts: ['0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e'] //account private key
}
},
docgen: {
pages: "files",
Expand Down
85 changes: 79 additions & 6 deletions test/OracleTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "../contracts/ProviderRegistry.sol";
import "../contracts/UserRegistry.sol";

contract OracleTest is Test {
using ECDSA for bytes32;
Oracle internal oracle;
PreConfCommitmentStore internal preConfCommitmentStore;
uint16 internal feePercent;
Expand All @@ -23,7 +24,7 @@ contract OracleTest is Test {

// Events to match against
event BlockDataRequested(uint256 blockNumber);
event BlockDataReceived(bytes32[] txnList, uint256 blockNumber, string blockBuilderName);
event BlockDataReceived(string[] txnList, uint256 blockNumber, string blockBuilderName);
event CommitmentProcessed(bytes32 commitmentHash, bool isSlash);

function setUp() public {
Expand All @@ -49,10 +50,13 @@ contract OracleTest is Test {

address signer = 0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3;
vm.deal(signer, 5 ether);
vm.prank(signer);
vm.startPrank(signer);
userRegistry.registerAndStake{value: 2 ether}();


// vm.prank(signer);
oracle = new Oracle(address(preConfCommitmentStore));
oracle.addBuilderAddress("mev builder", signer);
vm.stopPrank();

preConfCommitmentStore.updateOracle(address(oracle));
userRegistry.setPreconfirmationsContract(address(preConfCommitmentStore));
Expand All @@ -71,15 +75,84 @@ contract OracleTest is Test {
}

function test_ReceiveBlockData() public {
bytes32[] memory txnList = new bytes32[](1);
txnList[0] = keccak256("0xkartik");
string[] memory txnList = new string[](1);
txnList[0] = string(abi.encodePacked(keccak256("0xkartik")));
uint256 blockNumber = block.number;
string memory blockBuilderName = "mev builder";
vm.expectEmit(true, true, false, true);
emit BlockDataReceived(txnList, blockNumber, blockBuilderName);
oracle.receiveBlockData(txnList, blockNumber, blockBuilderName);
}

/**
constructAndStoreCommitment is a helper function to construct and store a commitment
*/
function constructAndStoreCommitment(
uint64 bid,
uint64 blockNumber,
string memory txnHash,
uint256 bidderPk,
uint256 signerPk
) public returns (bytes32 commitmentIndex) {
bytes32 bidHash = preConfCommitmentStore.getBidHash(
txnHash,
bid,
blockNumber
);


(uint8 v,bytes32 r, bytes32 s) = vm.sign(bidderPk, bidHash);
bytes memory bidSignature = abi.encodePacked(r, s, v);

bytes32 commitmentHash = preConfCommitmentStore.getPreConfHash(
txnHash,
bid,
blockNumber,
bidHash,
_bytesToHexString(bidSignature)
);

(v,r,s) = vm.sign(signerPk, commitmentHash);
bytes memory commitmentSignature = abi.encodePacked(r, s, v);

commitmentIndex = preConfCommitmentStore.storeCommitment(
bid,
blockNumber,
txnHash,
bidSignature,
commitmentSignature
);

return commitmentIndex;
}

function test_ReceiveBlockDataWithCommitments() public {
string[] memory txnList = new string[](1);
txnList[0] = string(abi.encodePacked(keccak256("0xkartik")));
uint64 blockNumber = 200;
uint64 bid = 2;
string memory blockBuilderName = "kartik builder";
(address user, uint256 userPk) = makeAddrAndKey("alice");

vm.deal(user, 200000 ether);
vm.startPrank(user);
userRegistry.registerAndStake{value: 250 ether }();
providerRegistry.registerAndStake{value: 250 ether}();
vm.stopPrank();

bytes32 commitmentIndex = constructAndStoreCommitment(bid, blockNumber, txnList[0], userPk, userPk);
vm.prank(address(0x6d503Fd50142C7C469C7c6B64794B55bfa6883f3));
oracle.addBuilderAddress("kartik builder", user);
vm.expectEmit(true, true, false, true);
emit BlockDataReceived(txnList, blockNumber, blockBuilderName);
oracle.receiveBlockData(txnList, blockNumber, blockBuilderName);

bytes32[] memory commitmentHashes = preConfCommitmentStore.getCommitmentsByBlockNumber(blockNumber);
assertEq(commitmentHashes.length, 1);
assertEq(userRegistry.getProviderAmount(user), bid);

}

// function test_ProcessCommitment_Slash() public {
// TODO(@ckartik): Add test
// }
Expand All @@ -98,7 +171,7 @@ contract OracleTest is Test {
);
bytes
memory commitmentSignature = hex"ff7e00cf5c2d0fa9ef7c5efdca68b285a664a3aab927eb779b464207f537551f4ff81b085acf78b58ecb8c96c9a4efcb2172a0287f5bf5819b49190f6e2d2d1e1b";
bytes32 commitmentIndex = preConfCommitmentStore.storeCommitment(bid, blockNumber, txnHash, cHash, bidSignature, commitmentSignature);
bytes32 commitmentIndex = preConfCommitmentStore.storeCommitment(bid, blockNumber, txnHash, bidSignature, commitmentSignature);

bytes32 bidHash = preConfCommitmentStore.getBidHash(
txnHash,
Expand Down
Loading

0 comments on commit 855a1db

Please sign in to comment.