Skip to content

Commit

Permalink
zkBeefy integration tests (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
seunlanlege authored Jan 23, 2024
1 parent 710ccfc commit ed40dd6
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 17 deletions.
3 changes: 2 additions & 1 deletion evm/script/deploy.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/bin/bash
if [ "$1" = "local" ]; then
echo "Deploying locally"
# load local .env
source .env
# deploy
HOST="ethereum" forge script script/DeployIsmp.s.sol:DeployScript --rpc-url "$GOERLI_RPC_URL" --broadcast --verify -vvvv --sender="$ADMIN"
HOST="ethereum" forge script script/DeployIsmp.s.sol:DeployScript --rpc-url "$GOERLI_RPC_URL" --broadcast -vvvv --sender="$ADMIN"
else
echo "Deploying to $1"
# load prod .env
Expand Down
31 changes: 19 additions & 12 deletions evm/src/beefy/ZkBeefy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ contract ZkBeefyV1 is IConsensusClient {

function verifyConsensus(bytes memory encodedState, bytes memory encodedProof)
external
view
returns (bytes memory, IntermediateState memory)
{
BeefyConsensusState memory consensusState = abi.decode(encodedState, (BeefyConsensusState));
Expand All @@ -69,7 +68,6 @@ contract ZkBeefyV1 is IConsensusClient {
/// by this consensus proof.
function verifyConsensus(BeefyConsensusState memory trustedState, BeefyConsensusProof memory proof)
internal
view
returns (BeefyConsensusState memory, IntermediateState memory)
{
// verify mmr root proofs
Expand All @@ -87,7 +85,6 @@ contract ZkBeefyV1 is IConsensusClient {
/// using a merkle multi proof and a merkle commitment to the total authorities.
function verifyMmrUpdateProof(BeefyConsensusState memory trustedState, PlonkConsensusProof memory relayProof)
internal
view
returns (BeefyConsensusState memory, bytes32)
{
uint256 latestHeight = relayProof.commitment.blockNumber;
Expand Down Expand Up @@ -131,7 +128,7 @@ contract ZkBeefyV1 is IConsensusClient {
// check BEEFY proof
require(_verifier.verify(relayProof.proof, inputs), "ZkBEEFY: Invalid plonk proof");

verifyMmrLeaf(relayProof, mmrRoot);
verifyMmrLeaf(trustedState, relayProof, mmrRoot);

if (relayProof.latestMmrLeaf.nextAuthoritySet.id > trustedState.nextAuthoritySet.id) {
trustedState.currentAuthoritySet = trustedState.nextAuthoritySet;
Expand All @@ -144,15 +141,16 @@ contract ZkBeefyV1 is IConsensusClient {
}

/// Stack too deep, sigh solidity
function verifyMmrLeaf(PlonkConsensusProof memory relay, bytes32 mmrRoot) internal pure {
bytes32 temp = keccak256(Codec.Encode(relay.latestMmrLeaf));
// bag peaks from right to left
uint256 i = relay.mmrProof.length;
for (; i > 0; i--) {
temp = keccak256(bytes.concat(temp, relay.mmrProof[i - 1]));
}
function verifyMmrLeaf(BeefyConsensusState memory trustedState, PlonkConsensusProof memory relay, bytes32 mmrRoot)
internal
{
bytes32 hash = keccak256(Codec.Encode(relay.latestMmrLeaf));
uint256 leafCount = leafIndex(trustedState.beefyActivationBlock, relay.latestMmrLeaf.parentNumber) + 1;

require(temp == mmrRoot, "Invalid Mmr Proof");
MmrLeaf[] memory leaves = new MmrLeaf[](1);
leaves[0] = MmrLeaf(relay.latestMmrLeaf.kIndex, relay.latestMmrLeaf.leafIndex, hash);

require(MerkleMountainRange.VerifyProof(mmrRoot, relay.mmrProof, leaves, leafCount), "Invalid Mmr Proof");
}

/// Verifies that some parachain header has been finalized, given the current trusted consensus state.
Expand Down Expand Up @@ -192,4 +190,13 @@ contract ZkBeefyV1 is IConsensusClient {

return IntermediateState(para.id, header.number, StateCommitment(timestamp, commitment, header.stateRoot));
}

/// Calculates the mmr leaf index for a block whose parent number is given.
function leafIndex(uint256 activationBlock, uint256 parentNumber) private pure returns (uint256) {
if (activationBlock == 0) {
return parentNumber;
} else {
return parentNumber - activationBlock;
}
}
}
25 changes: 25 additions & 0 deletions evm/test/ZkBeefyTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.17;

import "forge-std/Test.sol";

import {ZkBeefyV1, BeefyConsensusState} from "../src/beefy/ZkBeefy.sol";
import {RococoVerifier} from "../src/beefy/verifiers/RococoVerifier.sol";

contract BeefyConsensusClientTest is Test {
ZkBeefyV1 internal beefy;

function setUp() public virtual {
RococoVerifier verifier = new RococoVerifier();
beefy = new ZkBeefyV1(2000, verifier);
}

function testBeefyProof() public {
bytes memory proof =
hex"00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000ce00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008755e1942b2aad1859ad315aaaa081a458e59466244a64acbed651f67f493ae25701870000000000000000000000000000000000000000000000000000000000003b53000000000000000000000000000000000000000000000000000000000000006eab34ddb838b4f3f271d56c3fc2678c88cd735d9946ba100cb91ee698a53b44d3aa12de07c3b034ed158b9d6ed625e56e8fc20611e9b4790b1481a63ccec0894c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000004d4a6500000000000000000000000000000000000000000000000000000000000002a00000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000008755e20000000000000000000000000000000000000000000000000000000000003b52000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000206d680000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002043a2200c22127a11c6f9d6bc880de0cf9bbc5aa901d4235e7659943d38a8007e000000000000000000000000000000000000000000000000000000000000000bcdb32ad5cea2b0454fd8b3ff6307fa02fa6a435dbbc46dd2e0080b83eaa868ae5f053506d1054f84c6b7d350a03a83459591c4eec55d20fffd4b7c3b0a2e97a177de647be78b26c08ac6f538c94f2ce8f672603e2c78fc40441e5615f0d53ec1697c5ed32e1a9dce29ea5f94775a80a44aff3e62896c1a9f641bedd287488f9ea8c1623be7595ff68e168e65381dc49d6b8d00c404ff29a146f9b2bb6be2d2ad9ad42ffa93c51ba9fcc546026bbd05a59c59e32f874c18191b15cac9bde151b952caca1673be722c4de79dc51f77baff0824152c14d864532e592cfa26d608a03b9bd93710a5beb3466c41936ba2424091f7d07d91d018a6d8e7cc048f818b556540f73acf8c111513a2bb3bcbb8c52bfd4186e577c7081c8d9fbf79b09d883656b6f35c4e6b535aad5805fdce54ede948ddd807ed7d4caf8354b94b21bf8d0ca5b5ddc9822f6efff4cb05b28dbba19f3517ec755421179427db3139c014f6000000000000000000000000000000000000000000000000000000000000000860018247c70b697bc76583275854839658774c4466100d089b298f75fa67bea7da2db6f324bb52811f172d609eb909fa55cb3b72d8c80480869c0d795533c347a21bc172689ad14a46fefffc30a92a06be2f1f17635e130d94449f4e5653f23c402f355b56c098baaab9a2bad2433ed41d079002078ba5da26ca991c28a9a2d0d50e7e98441d9a9a142dfd53bec66fc3bfa1f321d19ec98cbdaeffdf74fcb4b8af0df5c1f1bfbc3805cafa72a0f57071bd956cee42a81624dc039d4e35ec8fea103038dda4afcd938f00e1d437b1e4eb5864f4f9327271c5d41db5a772bbb817581fba844fe23a866f9bde1ba3cbbac200bbb375f900bda9d83acbb6bf7aa79590289b0e178b3f2e473221c50c46fb7e46afb047f42c5d09f04ca57d24c34d01df1c427609a7d50e553ccd480b3f965a904ef329e76b9f8c248f1aef84aa9134442a6191543b3cb0291692ae290b5e810a47ab9d4a9812c0e561e1dd4c21f3d4112142400cc6b40172ce2b79afbcfff84714583783bbe3ef5815751b11f11111592ccd95ee549f066e4550f86033ed531643294862ac8e9bd38b67817294ea8ed42aa3ea0d1984c076145f1795b4b0ec94cfebf48d6d6269c61d752131cfd8b6b90f832e18228746e22ec7714b9ca554b49e2d881b7e621d638a00a676646b4a0118bb63bc6f7d85c882b3e6cacbf1671108a0263ab15b631ba6215f10c8ee22632d5c50226e8d0706d0faf30535c6b51d2006919c01a0d6fafbd08c6899e01cd31c9f60ac08163711d98f0b380e450aaef1f50b6d4fdfcf3b84619ff4d8f8f3332a8b10f2eea5395896d14be632539d970db2297d18168b2c6043cf61a7068122065153a2188ce09cc3f91ecfa96a6a2b3b9100c8e78bba4ba0edc8c009cf647426207cb486c6e42d23c3db3b0b50bea14faa8ccc30d4301c72eb059dd1538a140c64d169b88d038b5d16bbda1237b9113cf9f0c444a33fec4ea73c275f71c9e5238a5197f6851855d76e38acbf99f360889bfe8cbd65a9cec4993d9fbe48f2fa226b7a4cafeb0bb07274dcda0ec76053c71f84abe58e43aa22469757b61846990cdd271be8a2ed5633a421ef9c83c99e472bd23249427eb5f58de129da8a348f09eaf1fa26f8325e52a62363363f69a140c7798d8133e846674bef6b06981e4c2c9d30c2427e85059bec94d8919e6aac45d475eb577c82d8b3983ba5326af2d5300c6daba3091ec6ba9687b812b541117c3cd53a0562238aae8ea1f4bf0591a606acd05ca9e929e5036d1f8089929aff7819c3e94a13414d7f4e2d4393c08493138f94e6736193763a4c14e51dd254d2a133f91f87bab8b054c9aab2c4f61adb0de7b379879deb46cd5531102a1242d83425df25643eb1293a23c9ee9eb554d82bc0844b281d1a31a077cf70f0307e6354420bfdba4bd159336cdf2d98d1a4f3046ecf3778b6559ebd1837f3018618ff7345ea2ffce54187edab2949265dd7a9059ec0dc8d912e5fed660a5b66f422ab11649e4946e13364ffe6fd24ebdd582d0f106f55c9812eabacae42c100aad5399dc01c664d263bb73c33c36cd05870442d278d2a0564f657fce98043586db9550095142787f0bb39bb619a271f2d872422f9178fc60bf164c3e55acbe1bbfda94d71a806b22291c3065350f25b64da4917b0325495d0b13d741e22792a75316c0895738c81c8923f4cc686776be9738a0e8e2f0facb9ae0617a6711bf7eb33a953315a7f06adc91371da35c24db2514222f660c4fdb00905cc4c829665407db401983af9e9293bcab520d89e8d12419a0311206dfb35e29825f2e6d8cb66477e40166740bfd7b278807d2709f98b02e01d766ea6f65e4e3d719a8e56593c375c84b1c35d2301f36ca022ebcea5703424217d6940ec4ad04a8917217d6346244f23afc77e32fcb9896717a696aba58ac02f6ff9cc98994241ab0baf96bacf4a01d7c2096d3016a34b7acc2a5f305c44190f0c2b0202f89f481fdf0defc075ccbb349ea7ebc03e15236d521334fee464910cbc0ccdbb1fefa85e9194df8fe3b6372c9aa7c245505bcff2af38e366b0d0d014ebb4686691ef9d3f548c9dcebc0176607baaad457cbd95cbbc099115ff6f3e052a6933ec6d9a8f7047b72a76c6d0cb2cc722fca17111d319e737cb9966d04305a7bc3d56ff76b8e2760a71c152f6e10c66d6bef4289def68a2769e1702e5d0284ad6600650873acdbcd5a4501ffb354ce68136589d069e581cbc5562d387c0202157054b1f7230e89abc9c785cff3e9fc239990cc3f50e91af3a93afc7da99281a8b6cb153cf1cec70c92309587cb387399251730ec24c8c80836f701e7cb31894f85f162bfb6928f680c51a9760a5d5305a3df3df33b28f981ea37bbabcb4003dd9051f3d8407abc2e26fe87bd74613e13eb33a73030a14663958b4e6afcc0f0a166a55c2f87b841ba87dd33c460058c2c8b566202cbff65c96bb8657f9331baabb8cded80dc58cfe1eeddfb58b8a2e97371e951d46a7159659810a09a1682ff53adfc06d4dbf05ed8b70df831c88b81da38b4a21047204cf8ae8b6181076021aea3cf69f2b4f1b1401724c90a63780cdb721f5dc519909bf29249be4c7251ddbbe5df1a5f70171a727f3e8e0514768ee1cdae3cec8cd212f6bd2965ab932156ee2476bd8e9262be97758b8ace4e890ced9ce8bbc543d145db568a37bb075253b50e3fe364eaf08ee8123af51895bbcd7d184fe4a00b495031da6a4c326a92f511e9a22b39ecdbc469b66cfe25a76a0c492d23df0798e2cf7bf2d4c9b65301e7ac76b789bd8f98b84b7a3787b4a03dbcf62a3ab0957ffa4eaef190077696d2679c5a48882a564d8a03b3c70f7f1a74f843699f5d4134a8098a06d85b084d1131afd178bbc3502641532c8c5eba16cd6294b348e09a77a45513b96ede9cffd0163ddcc6e61c475c42b7846e914d5ea205223d8c01762e79520d8e00296f5350e3fb0b8b2138495b6c55262afd021668f46c66580a9151d4cca823060e4251100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000007d0000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000baef7cf3c41418e8b91ab4a62b0f61e9d7412c10d0459feb80d4db3a19eee54e75f29968000f969604f0444e069652e3d4a69e12ff83403f71d255946f7ce864b0b444219619ba0a4c43620f43cb720eabd7d83accde9780609467cbd2d7834ee259f09f8508066175726120038350080000000005617572610101d63af09482a0f01fd7ba59aadd4b3f47e882f72b751ed5cc7e99b19b25500042c7e13d45dcd9739c359f275bc57004099d416f1d8a75484b51e2a2b37cdbcf87000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000067ed65077fd16778ebc2324ccd9ba83dc4a3fa5f4b2f2ab81acb13a97e3e9f3b50000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000239713bbc4b67acccd08215ca1b73eea64f425aec497aa6b1ff78eb970df016f600000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000e8c79f35cd625e77a137a3c15f73fe93ef07d8b6839fa4fb56821881866363970000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000115849513fc4f20fd17f0964b912261d87fab01930058ab84e17bf5372fe2791d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e50653f89a025569f05d1160c4e0ae5d9ea06d0b9afcd4356e5927ebb0c1ff9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001e75cde1ce400af5a68ca2df7e9eca3d6d89b78955d093e2c0dd02a0c5fc9c5440000000000000000000000000000000000000000000000000000000000000000";
bytes memory state =
hex"00000000000000000000000000000000000000000000000000000000008752da00000000000000000000000000000000000000000000000000000000003a0b7c0000000000000000000000000000000000000000000000000000000000003b51000000000000000000000000000000000000000000000000000000000000006eab34ddb838b4f3f271d56c3fc2678c88cd735d9946ba100cb91ee698a53b44d30000000000000000000000000000000000000000000000000000000000003b52000000000000000000000000000000000000000000000000000000000000006eab34ddb838b4f3f271d56c3fc2678c88cd735d9946ba100cb91ee698a53b44d3";

beefy.verifyConsensus(state, proof);
}
}
3 changes: 0 additions & 3 deletions parachain/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ description = "The Hyperbridge coprocessor node"
edition = "2021"
build = "build.rs"

[package.metadata.dist]
features = ["sepolia"]

[dependencies]
# crates.io
clap = { version = "4.0.32", features = ["derive"] }
Expand Down
4 changes: 3 additions & 1 deletion scripts/ignore_plonk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ mv ./evm/src/beefy/verifiers/KusamaVerifier.sol ./evm/src/beefy/verifiers/Kusama
mv ./evm/src/beefy/verifiers/PolkadotVerifier.sol ./evm/src/beefy/verifiers/PolkadotVerifier
mv ./evm/src/beefy/verifiers/RococoVerifier.sol ./evm/src/beefy/verifiers/RococoVerifier
mv ./evm/test/PlonkTest.sol ./evm/test/PlonkTest
mv ./evm/test/ZkBeefyTest.sol ./evm/test/ZkBeefyTest

eval $1

mv ./evm/src/beefy/verifiers/KusamaVerifier ./evm/src/beefy/verifiers/KusamaVerifier.sol
mv ./evm/src/beefy/verifiers/PolkadotVerifier ./evm/src/beefy/verifiers/PolkadotVerifier.sol
mv ./evm/src/beefy/verifiers/RococoVerifier ./evm/src/beefy/verifiers/RococoVerifier.sol
mv ./evm/test/PlonkTest ./evm/test/PlonkTest.sol
mv ./evm/test/PlonkTest ./evm/test/PlonkTest.sol
mv ./evm/test/ZkBeefyTest ./evm/test/ZkBeefyTest.sol

0 comments on commit ed40dd6

Please sign in to comment.