Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gwyneth): add reth-based private network , and L1 contract deployment #19

Merged
merged 9 commits into from
Jul 15, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/protocol/.env_sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
L2_GENESIS_HASH=0xdf90a9c4daa571aa308e967c9a6b4bf21ba8842d95d73d28be112b6fe0618e8c
PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
MAINNET_CONTRACT_OWNER=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 #It shall belong to the PK above. I got this example ADDR-PK from local anvil.
148 changes: 148 additions & 0 deletions packages/protocol/contracts/L1/verifiers/MockSgxVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// SPDX-License-Identifier: MIT
// _____ _ _ _ _
// |_ _|_ _(_) |_____ | | __ _| |__ ___
// | |/ _` | | / / _ \ | |__/ _` | '_ (_-<
// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/

pragma solidity ^0.8.20;

import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "../../common/EssentialContract.sol";
import "../../thirdparty/LibBytesUtils.sol";

Check failure on line 11 in packages/protocol/contracts/L1/verifiers/MockSgxVerifier.sol

GitHub Actions / codespell

thirdparty ==> third party, third-party
import "../TaikoData.sol";
import "./IVerifier.sol";

/// @title SgxVerifier
/// @notice This contract is the implementation of verifying SGX signature
/// proofs on-chain. Please see references below!
/// Reference #1: https://ethresear.ch/t/2fa-zk-rollups-using-sgx/14462
/// Reference #2: https://github.com/gramineproject/gramine/discussions/1579
contract MockSgxVerifier is EssentialContract, IVerifier {
/// @dev Each public-private key pair (Ethereum address) is generated within
/// the SGX program when it boots up. The off-chain remote attestation
/// ensures the validity of the program hash and has the capability of
/// bootstrapping the network with trustworthy instances.
struct Instance {
address addr;
uint64 addedAt; // We can calculate if expired
}

uint256 public constant INSTANCE_EXPIRY = 180 days;

/// @dev For gas savings, we shall assign each SGX instance with an id
/// so that when we need to set a new pub key, just write storage once.
uint256 public nextInstanceId; // slot 1

/// @dev One SGX instance is uniquely identified (on-chain) by it's ECDSA
/// public key (or rather ethereum address). Once that address is used (by
/// proof verification) it has to be overwritten by a new one (representing
/// the same instance). This is due to side-channel protection. Also this
/// public key shall expire after some time. (For now it is a long enough 6
/// months setting.)
mapping(uint256 instanceId => Instance) public instances; // slot 2

uint256[48] private __gap;

event InstanceAdded(
uint256 indexed id, address indexed instance, address replaced, uint256 timstamp

Check failure on line 47 in packages/protocol/contracts/L1/verifiers/MockSgxVerifier.sol

GitHub Actions / codespell

timstamp ==> timestamp
);

error SGX_INVALID_INSTANCE();
error SGX_INVALID_INSTANCES();
error SGX_INVALID_PROOF();

/// @notice Initializes the contract with the provided address manager.
/// @param _addressManager The address of the address manager contract.
function init(address _addressManager) external initializer {
__Essential_init(_addressManager);
}

/// @notice Adds trusted SGX instances to the registry.
/// @param _instances The address array of trusted SGX instances.
/// @return ids The respective instanceId array per addresses.
function addInstances(address[] calldata _instances)
external
onlyOwner
returns (uint256[] memory ids)
{
if (_instances.length == 0) revert SGX_INVALID_INSTANCES();
ids = _addInstances(_instances);
}

/// @notice Adds SGX instances to the registry by another SGX instance.
/// @param id The id of the SGX instance who is adding new members.
/// @param newInstance The new address of this instance.
/// @param extraInstances The address array of SGX instances.
/// @param signature The signature proving authenticity.
/// @return ids The respective instanceId array per addresses.
function addInstances(
uint256 id,
address newInstance,
address[] calldata extraInstances,
bytes calldata signature
)
external
returns (uint256[] memory ids)
{
bytes32 signedHash = keccak256(abi.encode("ADD_INSTANCES", extraInstances));
address oldInstance = ECDSA.recover(signedHash, signature);
if (!_isInstanceValid(id, oldInstance)) revert SGX_INVALID_INSTANCE();

_replaceInstance(id, oldInstance, newInstance);

ids = _addInstances(extraInstances);
}

/// @inheritdoc IVerifier
/* MODIFIED- TO RETURN TRUE WITHOUT REAL VERIFICATION!!! */
function verifyProof(
TaikoData.BlockMetadata calldata /*_block*/,
TaikoData.Transition calldata /*transition*/,
address /*prover*/,
bytes calldata /*proof*/
)
external
{
return;
}

function getSignedHash(
TaikoData.Transition memory tran,
address newInstance,
address prover,
bytes32 metaHash
)
public
pure
returns (bytes32 signedHash)
{
return keccak256(abi.encode(tran, newInstance, prover, metaHash));
}

function _addInstances(address[] calldata _instances) private returns (uint256[] memory ids) {
ids = new uint256[](_instances.length);

for (uint256 i; i < _instances.length; ++i) {
if (_instances[i] == address(0)) revert SGX_INVALID_INSTANCE();

instances[nextInstanceId] = Instance(_instances[i], uint64(block.timestamp));
ids[i] = nextInstanceId;

emit InstanceAdded(nextInstanceId, _instances[i], address(0), block.timestamp);

nextInstanceId++;
}
}

function _replaceInstance(uint256 id, address oldInstance, address newInstance) private {
instances[id] = Instance(newInstance, uint64(block.timestamp));
emit InstanceAdded(id, newInstance, oldInstance, block.timestamp);
}

/* MODIFIED- TO RETURN TRUE IF INSTANCE ADDED!!! */
function _isInstanceValid(uint256 id, address instance) private view returns (bool) {
if (instance == address(0)) return false;
if (instance != instances[id].addr) return false;
return true;
}
}
55 changes: 55 additions & 0 deletions packages/protocol/deployments/local_deployment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# How to deploy Gwyneth locally - on a reth-based private network

The first part is coming from [Reth Book](https://reth.rs/run/private-testnet.html), but if you want to dig deeper, please visit the website, otherwise it is not necessary.

### 0. Pre-requisites:
- have docker installed (and docker daemon running)
- have Kurtosis installed, on Mac, e.g.:
```shell
brew install kurtosis-tech/tap/kurtosis-cli
```

### 1. Define the network config parameters

Create a `network_param.json` file.

```shell
{
"participants": [
{
"el_type": "reth",
"el_image": "ghcr.io/paradigmxyz/reth",# We can use custom image, like ethpandaops/reth:main-9c0bc84 with MacOs with M1 chip or taiko.xyz/taiko-reth for example
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Brechtpd @johntaiko This is where we can reference our taiko reth fork and run our network with that when ready to be tested.

"cl_type": "lighthouse",
"cl_image": "sigp/lighthouse:latest",
"count": 1
},
{
"el_type": "reth",
"el_image": "ghcr.io/paradigmxyz/reth", # We can use custom image, like ethpandaops/reth:main-9c0bc84 with MacOs with M1 chip or taiko.xyz/taiko-reth for example
"cl_type": "teku",
"cl_image": "consensys/teku:latest",
"count": 1
}
],
"launch_additional_services": false
}
```

### 2. Spin up the network

```shell
kurtosis run github.com/ethpandaops/ethereum-package --args-file YOUR_NETWORK_FILE/network_params.json
```

It will show you a lot of information in the terminal - along with the genesis info, network id, addresses with pre-funded ETH, etc.

### 3. Set .env vars and run deployment script
Paste one PK and ADDR pair from anvil output to .env file and set the correct corresponding (PRIVATE_KEY and MAINNET_CONTRACT_OWNER) variables.

Run script:

```shell
$ forge script --rpc-url http://127.0.0.1:52178 scripts/DeployL1Locally.s.sol -vvvv --broadcast --private-key <YOUR_PRIVATE_KEY> --legacy
```

Important: <YOUR_PRIVATE_KEY> shall be the same PK as you set in the ENV file.
12 changes: 0 additions & 12 deletions packages/protocol/script/Counter.s.sol

This file was deleted.

Loading
Loading