Skip to content

Commit

Permalink
feat: enable usage of chains without pre-existing deployments in axio…
Browse files Browse the repository at this point in the history
…m-std (#25)

* feat: enable usage of chains without pre-existing deployments in axiom-std

* chore: update axiom-client

* chore: update axiom-client

* chore: fix CI
  • Loading branch information
yi-sun authored May 28, 2024
1 parent 1e9c82c commit fb3a28d
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 38 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ jobs:
export PROVIDER_URI_MAINNET=${{ secrets.PROVIDER_URI_MAINNET }}
export PROVIDER_URI_SEPOLIA=${{ secrets.PROVIDER_URI_SEPOLIA }}
export PROVIDER_URI_BASE=${{ secrets.PROVIDER_URI_BASE }}
export PROVIDER_URI_GNOSIS=${{ secrets.PROVIDER_URI_GNOSIS }}
RUST_BACKTRACE=1 forge test -vvv
test-mac:
Expand Down Expand Up @@ -88,4 +89,5 @@ jobs:
export PROVIDER_URI_MAINNET=${{ secrets.PROVIDER_URI_MAINNET }}
export PROVIDER_URI_SEPOLIA=${{ secrets.PROVIDER_URI_SEPOLIA }}
export PROVIDER_URI_BASE=${{ secrets.PROVIDER_URI_BASE }}
export PROVIDER_URI_GNOSIS=${{ secrets.PROVIDER_URI_GNOSIS }}
RUST_BACKTRACE=1 forge test -vvv
18 changes: 15 additions & 3 deletions build/axiom-std-cli-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,17 +255,29 @@ var require_prove = __commonJS({
if (!targetChainId) {
throw new Error("`targetChainId` is required for blockhash oracle bridge type");
}
axiomV2QueryAddress = (0, address_1.getAxiomV2QueryBlockhashOracleAddress)({ sourceChainId, targetChainId });
if (sourceChainId == "1" && targetChainId == "8453") {
axiomV2QueryAddress = (0, address_1.getAxiomV2QueryBlockhashOracleAddress)({ sourceChainId, targetChainId });
} else {
axiomV2QueryAddress = "0xdEaDBEefDeaDbEefDeAdbeefDeAdbEEfAAaaAAaA";
}
} else if (broadcaster) {
if (!targetChainId) {
throw new Error("`targetChainId` is required for broadcaster bridge type");
}
if (!bridgeId) {
throw new Error("`bridgeId` is required for broadcaster bridge type");
}
axiomV2QueryAddress = (0, address_1.getAxiomV2QueryBroadcasterAddress)({ sourceChainId, targetChainId, bridgeId });
if (false) {
axiomV2QueryAddress = (0, address_1.getAxiomV2QueryBroadcasterAddress)({ sourceChainId, targetChainId, bridgeId });
} else {
axiomV2QueryAddress = "0xdEaDBEefDeaDbEefDeAdbeefDeAdbEEfAAaaAAaA";
}
} else {
axiomV2QueryAddress = (0, address_1.getAxiomV2QueryAddress)(sourceChainId);
if (sourceChainId in ["1", "11155111", "8453", "84532"]) {
axiomV2QueryAddress = (0, address_1.getAxiomV2QueryAddress)(sourceChainId);
} else {
axiomV2QueryAddress = "0xdEaDBEefDeaDbEefDeAdbeefDeAdbEEfAAaaAAaA";
}
}
let target;
if (blockhashOracle || broadcaster) {
Expand Down
18 changes: 15 additions & 3 deletions cli/prove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,29 @@ export const prove = async (
if (!targetChainId) {
throw new Error("`targetChainId` is required for blockhash oracle bridge type");
}
axiomV2QueryAddress = getAxiomV2QueryBlockhashOracleAddress({sourceChainId, targetChainId});
if (sourceChainId == "1" && targetChainId == "8453") {
axiomV2QueryAddress = getAxiomV2QueryBlockhashOracleAddress({sourceChainId, targetChainId});
} else {
axiomV2QueryAddress = "0xdEaDBEefDeaDbEefDeAdbeefDeAdbEEfAAaaAAaA";
}
} else if (broadcaster) {
if (!targetChainId) {
throw new Error("`targetChainId` is required for broadcaster bridge type");
}
if (!bridgeId) {
throw new Error("`bridgeId` is required for broadcaster bridge type");
}
axiomV2QueryAddress = getAxiomV2QueryBroadcasterAddress({sourceChainId, targetChainId, bridgeId});
if (false) {
axiomV2QueryAddress = getAxiomV2QueryBroadcasterAddress({sourceChainId, targetChainId: targetChainId!, bridgeId: bridgeId!});
} else {
axiomV2QueryAddress = "0xdEaDBEefDeaDbEefDeAdbeefDeAdbEEfAAaaAAaA";
}
} else {
axiomV2QueryAddress = getAxiomV2QueryAddress(sourceChainId);
if (sourceChainId in ["1", "11155111", "8453", "84532"]) {
axiomV2QueryAddress = getAxiomV2QueryAddress(sourceChainId);
} else {
axiomV2QueryAddress = "0xdEaDBEefDeaDbEefDeAdbeefDeAdbEEfAAaaAAaA";
}
}

let target;
Expand Down
3 changes: 2 additions & 1 deletion env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
PROVIDER_URI_SEPOLIA=
PROVIDER_URI_MAINNET=
PROVIDER_URI_BASE_SEPOLIA=
PROVIDER_URI_BASE=
PROVIDER_URI_BASE=
PROVIDER_URI_GNOSIS=
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ sepolia = "${PROVIDER_URI_SEPOLIA}"
mainnet = "${PROVIDER_URI_MAINNET}"
base-sepolia = "${PROVIDER_URI_BASE_SEPOLIA}"
base = "${PROVIDER_URI_BASE}"
gnosis = "${PROVIDER_URI_GNOSIS}"

[fmt]
bracket_spacing = true
Expand Down
26 changes: 13 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
"author": "Intrinsic Technologies",
"license": "MIT",
"dependencies": {
"@axiom-crypto/circuit": "2.1.0-alpha.7",
"@axiom-crypto/client": "2.1.0-alpha.7",
"@axiom-crypto/circuit": "2.1.0-alpha.12",
"@axiom-crypto/client": "2.1.0-alpha.12",
"commander": "^11.1.0",
"dotenv": "^16.4.5",
"viem": "^2.12.0"
"viem": "^2.13.1"
},
"devDependencies": {
"@types/node": "18.15.13",
Expand Down
28 changes: 14 additions & 14 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/AxiomCli.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ pragma solidity ^0.8.0;

library AxiomCli {
/// @dev The SHA256 hash of the Axiom CLI binary
bytes public constant CLI_SHASUM = hex"c9ebb0489e0c2db2b2b033a4ee0109af3e636090cfde44497fa0d6785f77db26";
bytes public constant CLI_SHASUM = hex"5ae07ff7d39f98884004eb6b0e0cb50cc311f092e92437dcf62d7c6a6ef0bb6d";
}
114 changes: 114 additions & 0 deletions test/HashiCrosschain.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "../src/AxiomTest.sol";
import { AxiomV2Client } from "@axiom-crypto/v2-periphery/client/AxiomV2Client.sol";

contract MockClient is AxiomV2Client {
/// @dev The chain ID of the chain whose data the callback is expected to be called from.
uint64 public callbackSourceChainId;

/// @dev The query schema of the query the client is expecting.
bytes32 public immutable QUERY_SCHEMA;

/// @dev Error returned if the `sourceChainId` does not match.
error SourceChainIdDoesNotMatch();

/// @dev Error returned if the `querySchema` does not match.
error QuerySchemaDoesNotMatch();

/// @notice Emitted after callback is made.
/// @param queryId The unique ID identifying the query.
/// @param axiomResults The results of the query.
/// @param extraData Additional data passed to the callback.
event MockClientEvent(uint256 indexed queryId, bytes32[] axiomResults, bytes extraData);

/// @notice Construct a new MockClient contract.
/// @param _axiomV2QueryAddress The address of the AxiomV2Query contract.
/// @param _callbackSourceChainId The ID of the chain the query reads from.
/// @param querySchema The query schema the client is expecting.
constructor(address _axiomV2QueryAddress, uint64 _callbackSourceChainId, bytes32 querySchema)
AxiomV2Client(_axiomV2QueryAddress)
{
callbackSourceChainId = _callbackSourceChainId;
QUERY_SCHEMA = querySchema;
}

/// @inheritdoc AxiomV2Client
function _validateAxiomV2Call(
AxiomCallbackType callbackType,
uint64 sourceChainId,
address caller,
bytes32 querySchema,
uint256 queryId,
bytes calldata extraData
) internal override {
if (sourceChainId != callbackSourceChainId) {
revert SourceChainIdDoesNotMatch();
}

if (querySchema != QUERY_SCHEMA) {
revert QuerySchemaDoesNotMatch();
}
}

/// @inheritdoc AxiomV2Client
function _axiomV2Callback(
uint64 sourceChainId,
address caller,
bytes32 querySchema,
uint256 queryId,
bytes32[] calldata axiomResults,
bytes calldata extraData
) internal override {
emit MockClientEvent(queryId, axiomResults, extraData);
}
}

contract GnosisHashiTest is AxiomTest {
using Axiom for Query;

struct AxiomInput {
uint64[] blockNumbers;
uint256[] slots;
address _address;
}

AxiomInput public input;
bytes32 public querySchema;

MockClient public client;

function setUp() public {
_createSelectForkAndSetupAxiomCrosschain("gnosis", "mainnet", 3_500_000, 1, true, 0);

uint64[] memory blockNumbers = new uint64[](3);
uint256[] memory slots = new uint256[](3);
for (uint256 i = 0; i < 3; i++) {
blockNumbers[i] = 4_205_938;
slots[i] = i;
}
input = AxiomInput({
blockNumbers: blockNumbers,
slots: slots,
_address: address(0x8018fe32fCFd3d166E8b4c4E37105318A84BA11b)
});

querySchema = axiomVm.readCircuit("test/circuit/array.circuit.ts");
client = new MockClient(axiomV2QueryAddress, MAINNET_CHAIN_ID, querySchema);
}

/// @dev Simple demonstration of testing an Axiom client contract using Axiom cheatcodes
function test_hashi_crosschain() public {
// create a query into Axiom with default parameters
Query memory q = query(querySchema, abi.encode(input), address(client));

// send the query to Axiom
q.send();

// prank fulfillment of the query, returning the Axiom results
bytes32[] memory results = q.prankFulfill();

bytes32[] memory expectedResults = q.peekResults();
}
}

0 comments on commit fb3a28d

Please sign in to comment.