Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{github.event.pull_request.head.repo.full_name}}
- uses: actions/cache@v2
- uses: actions/cache@v4
with:
path: |
~/.cargo/registry
Expand Down
66 changes: 41 additions & 25 deletions light-client/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
use crate::client_state::ClientState;
use crate::commitment::{
calculate_ibc_commitment_storage_key, decode_eip1184_rlp_proof, resolve_account, verify_proof,
};
use crate::consensus_state::ConsensusState;
use crate::errors::{ClientError, Error};
use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED};
use crate::header::Header;
use crate::message::ClientMessage;
use crate::misbehaviour::Misbehaviour;
use alloc::string::{String, ToString};
use alloc::vec::Vec;

use light_client::commitments::{
EmittedState, MisbehaviourProxyMessage, PrevState, TrustingPeriodContext,
UpdateStateProxyMessage, VerifyMembershipProxyMessage,
Expand All @@ -11,18 +20,9 @@ use light_client::{
CreateClientResult, Error as LightClientError, HostClientReader, LightClient, MisbehaviourData,
UpdateClientResult, UpdateStateData, VerifyMembershipResult, VerifyNonMembershipResult,
};
use parlia_ibc_proto::ibc::lightclients::parlia::v1::ProveState;
use patricia_merkle_trie::keccak::keccak_256;

use crate::client_state::ClientState;
use crate::commitment::{
calculate_ibc_commitment_storage_key, decode_eip1184_rlp_proof, verify_proof,
};
use crate::consensus_state::ConsensusState;
use crate::errors::{ClientError, Error};
use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED};
use crate::header::Header;
use crate::message::ClientMessage;
use crate::misbehaviour::Misbehaviour;
use prost::Message;

#[derive(Default)]
pub struct ParliaLightClient;
Expand Down Expand Up @@ -389,8 +389,10 @@ impl InnerLightClient {
path: &str,
value: Option<Vec<u8>>,
proof_height: &Height,
storage_proof_rlp: Vec<u8>,
proof: Vec<u8>,
) -> Result<StateID, Error> {
let prove_state = ProveState::decode(&*proof).map_err(Error::ProtoDecodeError)?;

let client_state =
ClientState::try_from(ctx.client_state(&client_id).map_err(Error::LCPError)?)?;
if client_state.frozen {
Expand All @@ -408,8 +410,21 @@ impl InnerLightClient {
ctx.consensus_state(&client_id, &proof_height)
.map_err(Error::LCPError)?,
)?;
let storage_root = consensus_state.state_root;
let storage_proof = decode_eip1184_rlp_proof(&storage_proof_rlp)?;

// verify account
let account = resolve_account(
&consensus_state.state_root,
&decode_eip1184_rlp_proof(&prove_state.account_proof)?,
&client_state.ibc_store_address,
)
.map_err(|e| Error::VerifyAccountError(alloc::boxed::Box::new(e)))?;

// verify storage
let storage_root = account
.storage_root
.try_into()
.map_err(Error::UnexpectedStorageRoot)?;
let storage_proof = decode_eip1184_rlp_proof(&prove_state.commitment_proof)?;
verify_proof(
&storage_root,
&storage_proof,
Expand Down Expand Up @@ -634,7 +649,6 @@ mod test {
input.trusted_previous_validators_hash,
input.new_current_validators_hash,
input.new_previous_validators_hash,
input.expected_storage_root,
hp.ibc_store_address(),
hp.network(),
)
Expand All @@ -653,7 +667,6 @@ mod test {
input.trusted_previous_validators_hash,
new_current_validators_hash,
new_previous_validators_hash,
input.expected_storage_root,
hp.ibc_store_address(),
hp.network(),
)
Expand All @@ -667,7 +680,6 @@ mod test {
trusted_previous_validator_hash: Hash,
new_current_validator_hash: Hash,
new_previous_validator_hash: Hash,
expected_storage_root: Hash,
ibc_store_address: Address,
chain_id: ChainId,
) {
Expand Down Expand Up @@ -703,7 +715,7 @@ mod test {
ConsensusState::try_from(data.new_any_consensus_state).unwrap();
assert_eq!(data.height, header.height());
assert_eq!(new_client_state.latest_height, header.height());
assert_eq!(new_consensus_state.state_root, expected_storage_root);
assert_eq!(new_consensus_state.state_root, header.state_root().clone());
assert_eq!(new_consensus_state.timestamp, header.timestamp().unwrap());
assert_eq!(
new_consensus_state.current_validators_hash,
Expand Down Expand Up @@ -897,9 +909,9 @@ mod test {

#[test]
fn test_success_verify_membership() {
let proof_height = new_height(0, 232);
let proof = hex!("f902ccf90211a06868e3a43071c06084145e2546b14ab7b49b4a073213228fd2fe5b9ad6978723a032238795ce6d015be83c499b744c7108308321b5c52b424bdfe851819470572ca0db54777eae7ba641adeb842ebae3b86206443a817af6211162cb7b8f54685722a094b114ebfe63288bd344dc06b50a25982f93b38ae7deb1c4f0085a80b76692fda087385f44c834ce1d100176adb7dabf314d3d3799e83cecbdbae8bf0047bbeb8da0afa75930fdc8b5bbcc7de9653a126bbd5e7480ba180117ac8f6448ac620fe881a0c9970b5bcfc0a37c601a907ab40e0d73fe4a19b00564ebfaa2962bc4659937e8a07c6b19783013eefd4b7362ea987dda4509b7a6f6b9fa765f4be79817023c9fefa0c928ae51650933cbdc43721f48a8d96b1ff49326b6afc59fe4441a6ab4ec6391a0c60665890ed3028fb4cc13ffe5b37f9eaf93886aa0920ea7aab00e5f36a58cb9a0341de64564e1cde279f15a152a41fc07b955ed8fb331e8fbb70b6ada2f4533c1a0eb2cfd02210dd040808b05b9fcb94d99fb459a04cbaae816a87b30224962b82fa0dbd758e0c3164e578837b817584efafc5582fa3ad872bc59ba20a0ff29d84438a0ad31c527b35a0c5a0f50c15bcba55b473de5ced9ab8c22736bc71ca7ff5f9e4fa03d448120e46b82861ae5eccd3a72e3c12f8cd350b466dc27586a1d6d58791212a08a70cfd0b8005d9c457f0d83b1a7b29244963fadf71fb1ce35764fe7141bc90080f8718080808080a0ce42aec576e424376d1bfec5089611170bedc488327075ec1c37905b2eb04a7b80808080a0e8c783a5d1417b9c3c59e642b630d1fb818a3ca870068c33a8d3b3114d1a31278080a05868dd463ca96a009a6bbf76fe9a9d904ca04e30b83a3759619f191367ce5b26808080f843a0203fc42ddf6c1b5bb218ce24e14c40af9e0eb127a5d76050d37d7369e2fc4a47a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4");
let state_root = hex!("4050c398b206f467b6d88cfd3d877a11f65701c37aabaa48d77466a63dfda9b7");
let proof_height = new_height(0, 738);
let proof = hex!("0af505f902f2f90211a04f83ce967cc6c1a2529ccf2b54bb3be0822b7743744741920404fbda8e5bdb3aa0db8637d650a3f84e9866766025b2bb9a5a0e82140f3ac1d332f115fec1e3b0bda04cf087ca4528dc62a099390d1e88599fe43e360e2646f2067fa69774d22bb9d5a02fa8fb4f045ffee58682f7f7d1632a4b55512473503d73c265a97c621130ee8ba06e6b444bd057494f76216f671296fc77f71f989757f6286e308fc729a831c2daa08833397e80b9bf4db549c07e23998e023fd913b9efe4fe7579683f0688feaf02a09a256ea18698ff3c4769827a5c5535dd9f41d46fc8a534e7b51f8528491f621fa00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea0509d388bca267ead3cdeb2fb1da55193163896375582b79fced7df03cd42434aa0332fbd17735f4ee7db0b843666e1a9f5d3548badb90f4d16dca9e3f5a2f8665aa0b41e8d7ccbd1ec75dd4a330448c1ff914edd77397f847ceedfcb572ac7167b6aa02fe37b63b375e12fb0fdcc08811c4d4a2bb26a7c6e41bd7d908cbebe5a4b1178a0552ad5d23c543dd80f4d67a07ff4a37ebb9aafdd4642896cb473a1ad1b8600efa0d1d0d41dc046765964df5525c60b570da17d0ef87c7149260d72964bf7e280eaa0961b764de3cab4ab392b16c5144b545559450aa049b0575404432d040e8e1073a09acb2dbadb531e821eb8550792af7ab2c2e28e6407684d1ccf16c617e9f2e75980f871808080808080a05ebb69a6e5bc89b334b1cad75c8d55200c99c57898fb169e5c8546bb28b1f0208080a07d9dea58356b953bf7a7c795839d9dd16308c53d9eb944220ccd450abb8cc32a8080a0be86509add424551c0bb5c3cec1dd284c32757f219f0734656cd6513042f581280808080f869a02012683435c076b898a6cac1c03e41900e379104fefd4219d99f7908cb59cfb3b846f8440180a06ea5e7725bac4fdcc9462d77ec416efd003279f73a17a704ff07761638dd75a3a032494e8a0290ede55debb28d7a770918ee5249905e686dbfb522511502e6d1f512ef04f9026cf901d1a0162127af53c48811cc74cdf24e010964baeaec592221807055543c1be14c201ba031799f0839c6730a89f62d19f3a8c2f90648dfca3985861d989df03f7e6ea9a6a0f937a5894d7e171d02a2d836277767bbd69ae8b1864c52895a88d5d122b4ecaea05941e53568bf1fd6afed7ec75461710e0d67b8bbb72d3624acbad5ca353e4442a00dbc39c9b9ecaf901a5cacd446681d1b84276c0616bb2a142be9496f313382f880a061ec1614e1bd375100556e845545603fd281acb6615ced8af3196edef144a5aba0e46989a7771a48d24f9eedbee7b4efb32dd14f999e9b93b2399b4e0e7b6258c4a04585530cd9a77cfc46ffe70b4504dee31d8ad7bfa39ff5d8211ffbdb01c40defa0a777235f4b048421956fee718662f9308b4abfd1fb6b9922c67b2be6e623a37da032de982ffbb84f0a299cb7a3754690719719a79a03ef28b5bc1a476d16fff68ea042bd726cdc87e10a4ba8b83bebe34cf3bfa2729197b2cf5aa7de952efad3e1a4a065e3229e20dfd0b22ab4e93675f6a0b31d68a9639ebbe89348153658d046b300a0fb5fdb08b2ad9c2fd5cb6c7f9a2fe5aa7d809091e7075203dbda9c45c3bd634fa0f0342ad7c7a1501268fc9c0b31780b591caa57bf1754768896ddc35d80a270338080f85180a045a7754fcde5049be7c870b19247aad336ffcd4e10203b5e8f64039de5e4126880a09b7d0212148d0c50bd45d674a078f75ba616cdb1eef88e78947f1b442fa69ee680808080808080808080808080f843a020dc93aa2071d8fee619b0413af2f932685da696e8852d2c3c8dd087a6f0ffa6a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4");
let state_root = hex!("b12f849b462b42954754ba3826ac6a97fb4f88ed820811a06640dd2edbc755ae");
let value = hex!("0a0b78782d7061726c69612d3012230a0131120d4f524445525f4f524445524544120f4f524445525f554e4f524445524544180322220a0b78782d7061726c69612d30120c636f6e6e656374696f6e2d301a050a03696263").to_vec();
let path = "connections/connection-0";
let result = do_test_verify_membership(
Expand All @@ -920,9 +932,9 @@ mod test {

#[test]
fn test_error_verify_membership() {
let proof_height = new_height(0, 232);
let proof = hex!("f902ccf90211a06868e3a43071c06084145e2546b14ab7b49b4a073213228fd2fe5b9ad6978723a032238795ce6d015be83c499b744c7108308321b5c52b424bdfe851819470572ca0db54777eae7ba641adeb842ebae3b86206443a817af6211162cb7b8f54685722a094b114ebfe63288bd344dc06b50a25982f93b38ae7deb1c4f0085a80b76692fda087385f44c834ce1d100176adb7dabf314d3d3799e83cecbdbae8bf0047bbeb8da0afa75930fdc8b5bbcc7de9653a126bbd5e7480ba180117ac8f6448ac620fe881a0c9970b5bcfc0a37c601a907ab40e0d73fe4a19b00564ebfaa2962bc4659937e8a07c6b19783013eefd4b7362ea987dda4509b7a6f6b9fa765f4be79817023c9fefa0c928ae51650933cbdc43721f48a8d96b1ff49326b6afc59fe4441a6ab4ec6391a0c60665890ed3028fb4cc13ffe5b37f9eaf93886aa0920ea7aab00e5f36a58cb9a0341de64564e1cde279f15a152a41fc07b955ed8fb331e8fbb70b6ada2f4533c1a0eb2cfd02210dd040808b05b9fcb94d99fb459a04cbaae816a87b30224962b82fa0dbd758e0c3164e578837b817584efafc5582fa3ad872bc59ba20a0ff29d84438a0ad31c527b35a0c5a0f50c15bcba55b473de5ced9ab8c22736bc71ca7ff5f9e4fa03d448120e46b82861ae5eccd3a72e3c12f8cd350b466dc27586a1d6d58791212a08a70cfd0b8005d9c457f0d83b1a7b29244963fadf71fb1ce35764fe7141bc90080f8718080808080a0ce42aec576e424376d1bfec5089611170bedc488327075ec1c37905b2eb04a7b80808080a0e8c783a5d1417b9c3c59e642b630d1fb818a3ca870068c33a8d3b3114d1a31278080a05868dd463ca96a009a6bbf76fe9a9d904ca04e30b83a3759619f191367ce5b26808080f843a0203fc42ddf6c1b5bb218ce24e14c40af9e0eb127a5d76050d37d7369e2fc4a47a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4");
let state_root = hex!("4050c398b206f467b6d88cfd3d877a11f65701c37aabaa48d77466a63dfda9b7");
let proof_height = new_height(0, 738);
let proof = hex!("0af505f902f2f90211a04f83ce967cc6c1a2529ccf2b54bb3be0822b7743744741920404fbda8e5bdb3aa06471fc474647b4776b34d1230c491cfd980bf33122f5956eff4eeefdf400431fa04cf087ca4528dc62a099390d1e88599fe43e360e2646f2067fa69774d22bb9d5a02824f5075c1fb398bab7ea258ee18a360b9639a1a31c6c604b13a492ca16394ea06e6b444bd057494f76216f671296fc77f71f989757f6286e308fc729a831c2daa099bf4775a4d089d01c6ffec506dfbb1eb64a13502604fa7477699b29e22b8b5ea03da8f11404097583100dd1eb02f762ccf0091ca84d6b118c644bf9cf900b7caaa00577e3e2c4649c5a23cbdabe0bbfed7cdf6e85c136d84d58127cdec86264ad6ea0509d388bca267ead3cdeb2fb1da55193163896375582b79fced7df03cd42434aa0332fbd17735f4ee7db0b843666e1a9f5d3548badb90f4d16dca9e3f5a2f8665aa0b41e8d7ccbd1ec75dd4a330448c1ff914edd77397f847ceedfcb572ac7167b6aa02fe37b63b375e12fb0fdcc08811c4d4a2bb26a7c6e41bd7d908cbebe5a4b1178a0552ad5d23c543dd80f4d67a07ff4a37ebb9aafdd4642896cb473a1ad1b8600efa0d1d0d41dc046765964df5525c60b570da17d0ef87c7149260d72964bf7e280eaa0961b764de3cab4ab392b16c5144b545559450aa049b0575404432d040e8e1073a09acb2dbadb531e821eb8550792af7ab2c2e28e6407684d1ccf16c617e9f2e75980f871808080808080a05ebb69a6e5bc89b334b1cad75c8d55200c99c57898fb169e5c8546bb28b1f0208080a07d9dea58356b953bf7a7c795839d9dd16308c53d9eb944220ccd450abb8cc32a8080a0be86509add424551c0bb5c3cec1dd284c32757f219f0734656cd6513042f581280808080f869a02012683435c076b898a6cac1c03e41900e379104fefd4219d99f7908cb59cfb3b846f8440180a06ea5e7725bac4fdcc9462d77ec416efd003279f73a17a704ff07761638dd75a3a032494e8a0290ede55debb28d7a770918ee5249905e686dbfb522511502e6d1f512ef04f9026cf901d1a0162127af53c48811cc74cdf24e010964baeaec592221807055543c1be14c201ba031799f0839c6730a89f62d19f3a8c2f90648dfca3985861d989df03f7e6ea9a6a0f937a5894d7e171d02a2d836277767bbd69ae8b1864c52895a88d5d122b4ecaea05941e53568bf1fd6afed7ec75461710e0d67b8bbb72d3624acbad5ca353e4442a00dbc39c9b9ecaf901a5cacd446681d1b84276c0616bb2a142be9496f313382f880a061ec1614e1bd375100556e845545603fd281acb6615ced8af3196edef144a5aba0e46989a7771a48d24f9eedbee7b4efb32dd14f999e9b93b2399b4e0e7b6258c4a04585530cd9a77cfc46ffe70b4504dee31d8ad7bfa39ff5d8211ffbdb01c40defa0a777235f4b048421956fee718662f9308b4abfd1fb6b9922c67b2be6e623a37da032de982ffbb84f0a299cb7a3754690719719a79a03ef28b5bc1a476d16fff68ea042bd726cdc87e10a4ba8b83bebe34cf3bfa2729197b2cf5aa7de952efad3e1a4a065e3229e20dfd0b22ab4e93675f6a0b31d68a9639ebbe89348153658d046b300a0fb5fdb08b2ad9c2fd5cb6c7f9a2fe5aa7d809091e7075203dbda9c45c3bd634fa0f0342ad7c7a1501268fc9c0b31780b591caa57bf1754768896ddc35d80a270338080f85180a045a7754fcde5049be7c870b19247aad336ffcd4e10203b5e8f64039de5e4126880a09b7d0212148d0c50bd45d674a078f75ba616cdb1eef88e78947f1b442fa69ee680808080808080808080808080f843a020dc93aa2071d8fee619b0413af2f932685da696e8852d2c3c8dd087a6f0ffa6a1a038841326d6f11b905566840b11a81201594ec536da63c44f38c1681ddad3eee4");
let state_root = hex!("8617db342e8a02bf863ef25096db1ec2b5d665df743e789828ba626c88d41cf3");
let value = hex!("0a0b78782d7061726c69612d3012230a0131120d4f524445525f4f524445524544120f4f524445525f554e4f524445524544180322220a0b78782d7061726c69612d30120c636f6e6e656374696f6e2d301a050a03696263").to_vec();
let path = "connections/connection-0";

Expand Down Expand Up @@ -990,6 +1002,10 @@ mod test {
let ctx = MockClientReader {
client_state: Some(ClientState {
latest_height,
ibc_store_address: hex!("aa43d337145E8930d01cb4E60Abf6595C692921E"),
ibc_commitments_slot: hex!(
"1ee222554989dda120e26ecacf756fe1235cd8d726706b57517715dde4f0c900"
),
frozen,
..Default::default()
}),
Expand Down
41 changes: 1 addition & 40 deletions light-client/src/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use prost::Message as _;
use parlia_ibc_proto::google::protobuf::Any as IBCAny;
use parlia_ibc_proto::ibc::lightclients::parlia::v1::ClientState as RawClientState;

use crate::commitment::resolve_account;
use crate::consensus_state::ConsensusState;
use crate::errors::Error;
use crate::header::hardfork::{MINIMUM_HEIGHT_SUPPORTED, MINIMUM_TIMESTAMP_SUPPORTED};
Expand Down Expand Up @@ -65,18 +64,8 @@ impl ClientState {
new_client_state.latest_height = header_height;
}

// Ensure world state is valid
let account = resolve_account(
header.state_root(),
&header.account_proof()?,
&new_client_state.ibc_store_address,
)?;

let new_consensus_state = ConsensusState {
state_root: account
.storage_root
.try_into()
.map_err(Error::UnexpectedStorageRoot)?,
state_root: *header.state_root(),
timestamp: header.timestamp()?,
current_validators_hash: header.current_epoch_validators_hash(),
previous_validators_hash: header.previous_epoch_validators_hash(),
Expand Down Expand Up @@ -349,34 +338,6 @@ mod test {
}
err => unreachable!("{:?}", err),
}

// fail: resolve_account
let header = Header::new(
vec![1],
ETHHeaders {
target: hp.epoch_header(),
all: vec![
hp.epoch_header(),
hp.epoch_header_plus_1(),
hp.epoch_header_plus_2(),
],
},
Height {
revision_number: 0,
revision_height: h.number - 1,
},
hp.previous_epoch_header().epoch.unwrap(),
hp.epoch_header().epoch.unwrap(),
);
let err = cs
.check_header_and_update_state(now, &cons_state, header)
.unwrap_err();
match err {
Error::InvalidProofFormatError(value) => {
assert_eq!(value, vec![1]);
}
err => unreachable!("{:?}", err),
}
}

#[rstest]
Expand Down
4 changes: 4 additions & 0 deletions light-client/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub enum Error {
UnknownMisbehaviourType(String),
UnexpectedClientType(String),
LCPCommitmentError(CommitmentError),
VerifyAccountError(alloc::boxed::Box<Error>),

// ClientState error
MissingLatestHeight,
Expand Down Expand Up @@ -396,6 +397,9 @@ impl core::fmt::Display for Error {
Error::UnexpectedHeaderRLP(e1) => {
write!(f, "UnexpectedHeaderRLP : {}", e1)
}
Error::VerifyAccountError(e1) => {
write!(f, "VerifyAccountError : {}", e1)
}
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions light-client/src/fixture/localnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ impl Network for Localnet {
trusted_height: 501,
trusted_current_validators_hash: hex!("92f25eb8500cae7c8548a61c6a03f4fc99690589b472b55e4c8ce25d0ce0f4d5"),
trusted_previous_validators_hash: hex!("5b514a7e8083146842c425a71aec83368ef4628442999a6d340d623ffb360c67"),
expected_storage_root: hex!("e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9")
}
}

Expand All @@ -79,7 +78,6 @@ impl Network for Localnet {
trusted_previous_validators_hash: hex!("399334b2051da932262b42f25e5e59724c08df5c88d13c9d6bf5c51c33233aab"),
new_current_validators_hash: hex!("92f25eb8500cae7c8548a61c6a03f4fc99690589b472b55e4c8ce25d0ce0f4d5"),
new_previous_validators_hash: hex!("5b514a7e8083146842c425a71aec83368ef4628442999a6d340d623ffb360c67"),
expected_storage_root: hex!("e39304f0ec064a98e4b0a96432dfb0a9e4c7fd0f26a6bbcf9c75bff68c51a7a9")
}
}
fn error_update_client_non_neighboring_epoch_input(&self) -> Vec<u8> {
Expand Down
2 changes: 0 additions & 2 deletions light-client/src/fixture/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ pub struct UpdateClientNonEpochInput {
pub trusted_height: u64,
pub trusted_current_validators_hash: Hash,
pub trusted_previous_validators_hash: Hash,
pub expected_storage_root: Hash,
}

pub struct UpdateClientEpochInput {
Expand All @@ -54,7 +53,6 @@ pub struct UpdateClientEpochInput {
pub trusted_previous_validators_hash: Hash,
pub new_current_validators_hash: Hash,
pub new_previous_validators_hash: Hash,
pub expected_storage_root: Hash,
}

pub fn localnet() -> Box<dyn Network> {
Expand Down
Loading
Loading