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

imp(e2e): enable quick testing with 'SP1_PROVER=mock' #21

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
export MNEMONIC="YOUR_MNEMONIC"
# Private key with the permission to use the network prover
SP1_PRIVATE_KEY="PRIVATE_KEY"
# SP1_PROVER={network|local|mock}
SP1_PROVER=network
52 changes: 42 additions & 10 deletions e2e/interchaintestv8/ibc_eureka_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context) {

eth, simd := s.ChainA, s.ChainB

var prover string
s.Require().True(s.Run("Set up environment", func() {
err := os.Chdir("../..")
s.Require().NoError(err)
Expand All @@ -92,9 +93,20 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context) {
s.faucet, err = crypto.HexToECDSA(testvalues.FaucetPrivateKey)
s.Require().NoError(err)

prover = os.Getenv(testvalues.EnvKeySp1Prover)
switch prover {
case "":
prover = testvalues.EnvValueSp1Prover_Network
case testvalues.EnvValueSp1Prover_Mock:
s.T().Logf("Using mock prover")
case testvalues.EnvValueSp1Prover_Network:
default:
s.Require().Fail("invalid prover type: %s", prover)
}

os.Setenv(testvalues.EnvKeyEthRPC, eth.GetHostRPCAddress())
os.Setenv(testvalues.EnvKeyTendermintRPC, simd.GetHostRPCAddress())
os.Setenv(testvalues.EnvKeySp1Prover, "network")
os.Setenv(testvalues.EnvKeySp1Prover, prover)
os.Setenv(testvalues.EnvKeyOperatorPrivateKey, hex.EncodeToString(crypto.FromECDSA(operatorKey)))
// make sure that the SP1_PRIVATE_KEY is set.
s.Require().NotEmpty(os.Getenv(testvalues.EnvKeySp1PrivateKey))
Expand Down Expand Up @@ -122,15 +134,35 @@ func (s *IbcEurekaTestSuite) SetupSuite(ctx context.Context) {
"-o", "e2e/artifacts/genesis.json",
))

stdout, stderr, err := eth.ForgeScript(ctx, s.deployer.KeyName(), ethereum.ForgeScriptOpts{
ContractRootDir: ".",
SolidityContract: "script/E2ETestDeploy.s.sol",
RawOptions: []string{
"--json",
"--sender", s.deployer.FormattedAddress(), // This, combined with the keyname, makes msg.sender the deployer
},
})
s.Require().NoError(err, fmt.Sprintf("error deploying contracts: \nstderr: %s\nstdout: %s", stderr, stdout))
var (
stdout []byte
stderr []byte
err error
)
switch prover {
case testvalues.EnvValueSp1Prover_Mock:
stdout, stderr, err = eth.ForgeScript(ctx, s.deployer.KeyName(), ethereum.ForgeScriptOpts{
ContractRootDir: ".",
SolidityContract: "script/MockE2ETestDeploy.s.sol",
RawOptions: []string{
"--json",
"--sender", s.deployer.FormattedAddress(), // This, combined with the keyname, makes msg.sender the deployer
},
})
s.Require().NoError(err, fmt.Sprintf("error deploying contracts: \nstderr: %s\nstdout: %s", stderr, stdout))
case testvalues.EnvValueSp1Prover_Network:
stdout, stderr, err = eth.ForgeScript(ctx, s.deployer.KeyName(), ethereum.ForgeScriptOpts{
ContractRootDir: ".",
SolidityContract: "script/E2ETestDeploy.s.sol",
RawOptions: []string{
"--json",
"--sender", s.deployer.FormattedAddress(), // This, combined with the keyname, makes msg.sender the deployer
},
})
s.Require().NoError(err, fmt.Sprintf("error deploying contracts: \nstderr: %s\nstdout: %s", stderr, stdout))
default:
s.Require().Fail("invalid prover type: %s", prover)
}

client, err := ethclient.Dial(eth.GetHostRPCAddress())
s.Require().NoError(err)
Expand Down
5 changes: 5 additions & 0 deletions e2e/interchaintestv8/testvalues/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ const (
// EnvKeySp1PrivateKey Private key for the prover network.
EnvKeySp1PrivateKey = "SP1_PRIVATE_KEY"

// EnvValueSp1Prover_Network is the prover type for the network prover.
EnvValueSp1Prover_Network = "network"
// EnvValueSp1Prover_Mock is the prover type for the mock prover.
EnvValueSp1Prover_Mock = "mock"

// FaucetPrivateKey is the private key of the faucet account.
// '0x' prefix is trimmed.
FaucetPrivateKey = "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
Expand Down
4 changes: 4 additions & 0 deletions script/E2ETestDeploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

/*
This script is used for end-to-end testing with SP1_PROVER=network.
*/

import { stdJson } from "forge-std/StdJson.sol";
import { Script } from "forge-std/Script.sol";
import { SP1ICS07Tendermint } from "@cosmos/sp1-ics07-tendermint/SP1ICS07Tendermint.sol";
Expand Down
101 changes: 101 additions & 0 deletions script/MockE2ETestDeploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

/*
This script is used for local testing with SP1_PROVER=mock.
*/

import { stdJson } from "forge-std/StdJson.sol";
import { Script } from "forge-std/Script.sol";
import { SP1ICS07Tendermint } from "@cosmos/sp1-ics07-tendermint/SP1ICS07Tendermint.sol";
import { IICS07TendermintMsgs } from "@cosmos/sp1-ics07-tendermint/msgs/IICS07TendermintMsgs.sol";
import { ICS02Client } from "../src/ICS02Client.sol";
import { ICS26Router } from "../src/ICS26Router.sol";
import { ICS20Transfer } from "../src/ICS20Transfer.sol";
import { TestERC20 } from "../test/TestERC20.sol";
import { AcceptAllSP1Verifier } from "../test/AcceptAllSP1Verifier.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { ICS20Lib } from "../src/utils/ICS20Lib.sol";

struct SP1ICS07TendermintGenesisJson {
bytes trustedClientState;
bytes trustedConsensusState;
bytes32 updateClientVkey;
bytes32 membershipVkey;
bytes32 ucAndMembershipVkey;
}

/// @dev See the Solidity Scripting tutorial: https://book.getfoundry.sh/tutorials/solidity-scripting
contract MockE2ETestDeploy is Script {
using stdJson for string;

string public constant E2E_FAUCET = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266";

function run() public returns (string memory) {
// Read the initialization parameters for the SP1 Tendermint contract.
SP1ICS07TendermintGenesisJson memory genesis = loadGenesis("genesis.json");
IICS07TendermintMsgs.ConsensusState memory trustedConsensusState =
abi.decode(genesis.trustedConsensusState, (IICS07TendermintMsgs.ConsensusState));
bytes32 trustedConsensusHash = keccak256(abi.encode(trustedConsensusState));

vm.startBroadcast();
address deployerAddress = msg.sender; // This is being set in the e2e test

// Deploy the SP1 ICS07 Tendermint light client
AcceptAllSP1Verifier verifier = new AcceptAllSP1Verifier();
SP1ICS07Tendermint ics07Tendermint = new SP1ICS07Tendermint(
genesis.updateClientVkey,
genesis.membershipVkey,
genesis.ucAndMembershipVkey,
address(verifier),
genesis.trustedClientState,
trustedConsensusHash
);

// Deploy IBC Eureka
ICS02Client ics02Client = new ICS02Client(deployerAddress);
ICS26Router ics26Router = new ICS26Router(address(ics02Client), deployerAddress);
ICS20Transfer ics20Transfer = new ICS20Transfer(address(ics26Router));
TestERC20 erc20 = new TestERC20();

// Wire Transfer app
ics26Router.addIBCApp("transfer", address(ics20Transfer));

// Mint some tokens
(address addr, bool ok) = ICS20Lib.hexStringToAddress(E2E_FAUCET);
require(ok, "invalid address");
erc20.mint(addr, 100_000_000_000);

vm.stopBroadcast();

string memory json = "json";
json.serialize("ics07Tendermint", Strings.toHexString(address(ics07Tendermint)));
json.serialize("ics02Client", Strings.toHexString(address(ics02Client)));
json.serialize("ics26Router", Strings.toHexString(address(ics26Router)));
json.serialize("ics20Transfer", Strings.toHexString(address(ics20Transfer)));
string memory finalJson = json.serialize("erc20", Strings.toHexString(address(erc20)));

return finalJson;
}

function loadGenesis(string memory fileName) public view returns (SP1ICS07TendermintGenesisJson memory) {
string memory root = vm.projectRoot();
string memory path = string.concat(root, "/e2e/artifacts/", fileName);
string memory json = vm.readFile(path);
bytes memory trustedClientState = json.readBytes(".trustedClientState");
bytes memory trustedConsensusState = json.readBytes(".trustedConsensusState");
bytes32 updateClientVkey = json.readBytes32(".updateClientVkey");
bytes32 membershipVkey = json.readBytes32(".membershipVkey");
bytes32 ucAndMembershipVkey = json.readBytes32(".ucAndMembershipVkey");

SP1ICS07TendermintGenesisJson memory fixture = SP1ICS07TendermintGenesisJson({
trustedClientState: trustedClientState,
trustedConsensusState: trustedConsensusState,
updateClientVkey: updateClientVkey,
membershipVkey: membershipVkey,
ucAndMembershipVkey: ucAndMembershipVkey
});

return fixture;
}
}
15 changes: 15 additions & 0 deletions test/AcceptAllSP1Verifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.25 <0.9.0;

// solhint-disable no-empty-blocks

import { ISP1Verifier } from "@sp1-contracts/ISP1Verifier.sol";

/// @dev This SP1 verifier accepts all proofs, for testing purposes.
/// @dev It is required due to the issues we are running into with '@sp1-contracts/SP1MockVerifier.sol'.
/// @dev This contract can be removed once the issues are resolved.
contract AcceptAllSP1Verifier is ISP1Verifier {
function verifyProof(bytes32, bytes calldata, bytes calldata) external view override {
// Accept all proofs
}
}
Loading