diff --git a/target_chains/starknet/contracts/src/hash.cairo b/target_chains/starknet/contracts/src/hash.cairo index 3032afe9..6f3c07f4 100644 --- a/target_chains/starknet/contracts/src/hash.cairo +++ b/target_chains/starknet/contracts/src/hash.cairo @@ -55,8 +55,7 @@ pub impl HasherImpl of HasherTrait { /// Reads all remaining data from the reader and pushes it to /// the hashing buffer. - fn push_reader(ref self: Hasher, ref reader: Reader) -> Result<(), pyth::reader::Error> { - let mut result = Result::Ok(()); + fn push_reader(ref self: Hasher, ref reader: Reader) { while reader.len() > 0 { let mut chunk_len = 8 - self.num_last_bytes; if reader.len() < chunk_len.into() { @@ -66,8 +65,7 @@ pub impl HasherImpl of HasherTrait { let value = reader.read_num_bytes(chunk_len); // chunk_len <= 8 so value must fit in u64. self.push_to_last(value.try_into().expect(UNEXPECTED_OVERFLOW), chunk_len); - }; - result + } } /// Returns the keccak256 hash of the buffer. The output hash is interpreted diff --git a/target_chains/starknet/contracts/src/merkle_tree.cairo b/target_chains/starknet/contracts/src/merkle_tree.cairo index ba6e9cce..e715698b 100644 --- a/target_chains/starknet/contracts/src/merkle_tree.cairo +++ b/target_chains/starknet/contracts/src/merkle_tree.cairo @@ -27,7 +27,7 @@ impl ResultReaderToMerkleVerification of ResultReaderToMerkleVerificationTrai fn leaf_hash(mut reader: Reader) -> Result { let mut hasher = HasherImpl::new(); hasher.push_u8(MERKLE_LEAF_PREFIX); - hasher.push_reader(ref reader)?; + hasher.push_reader(ref reader); let hash = hasher.finalize() / ONE_SHIFT_96; Result::Ok(hash) } diff --git a/target_chains/starknet/contracts/src/pyth.cairo b/target_chains/starknet/contracts/src/pyth.cairo index 35a982e1..3dd319cc 100644 --- a/target_chains/starknet/contracts/src/pyth.cairo +++ b/target_chains/starknet/contracts/src/pyth.cairo @@ -382,7 +382,7 @@ mod pyth { let wh_proof_size = reader.read_u16(); let wh_proof = reader.read_byte_array(wh_proof_size.into()); let wormhole = IWormholeDispatcher { contract_address: self.wormhole_address.read() }; - let vm = wormhole.parse_and_verify_vm(wh_proof).map_err()?; + let vm = wormhole.parse_and_verify_vm(wh_proof); let source = DataSource { emitter_chain_id: vm.emitter_chain_id, emitter_address: vm.emitter_address diff --git a/target_chains/starknet/contracts/src/wormhole.cairo b/target_chains/starknet/contracts/src/wormhole.cairo index e51bb5cd..136b3786 100644 --- a/target_chains/starknet/contracts/src/wormhole.cairo +++ b/target_chains/starknet/contracts/src/wormhole.cairo @@ -4,10 +4,8 @@ use pyth::util::UnwrapWithFelt252; #[starknet::interface] pub trait IWormhole { - fn submit_new_guardian_set( - ref self: T, set_index: u32, guardians: Array - ) -> Result<(), SubmitNewGuardianSetError>; - fn parse_and_verify_vm(self: @T, encoded_vm: ByteArray) -> Result; + fn submit_new_guardian_set(ref self: T, set_index: u32, guardians: Array); + fn parse_and_verify_vm(self: @T, encoded_vm: ByteArray) -> VM; } #[derive(Drop, Debug, Clone, Serde)] @@ -127,16 +125,6 @@ mod wormhole { use pyth::hash::{Hasher, HasherImpl}; use pyth::util::{ONE_SHIFT_160, UNEXPECTED_OVERFLOW}; - #[generate_trait] - impl ResultReaderToWormhole of ResultReaderToWormholeTrait { - fn map_err(self: Result) -> Result { - match self { - Result::Ok(v) => Result::Ok(v), - Result::Err(err) => Result::Err(ParseAndVerifyVmError::Reader(err)), - } - } - } - #[derive(Drop, Debug, Clone, Serde, starknet::Store)] struct GuardianSet { num_guardians: usize, @@ -159,29 +147,24 @@ mod wormhole { ) { self.owner.write(owner); let set_index = 0; - store_guardian_set(ref self, set_index, @initial_guardians).unwrap_with_felt252(); + store_guardian_set(ref self, set_index, @initial_guardians); } - fn store_guardian_set( - ref self: ContractState, set_index: u32, guardians: @Array - ) -> Result<(), SubmitNewGuardianSetError> { + fn store_guardian_set(ref self: ContractState, set_index: u32, guardians: @Array) { if guardians.len() == 0 { - return Result::Err(SubmitNewGuardianSetError::NoGuardiansSpecified.into()); + panic_with_felt252(SubmitNewGuardianSetError::NoGuardiansSpecified.into()); } if guardians.len() >= 256 { - return Result::Err(SubmitNewGuardianSetError::TooManyGuardians.into()); + panic_with_felt252(SubmitNewGuardianSetError::TooManyGuardians.into()); } let mut i = 0; - let mut result = Result::Ok(()); while i < guardians.len() { if *guardians.at(i) == 0 { - result = Result::Err(SubmitNewGuardianSetError::InvalidGuardianKey.into()); - break; + panic_with_felt252(SubmitNewGuardianSetError::InvalidGuardianKey.into()); } i += 1; }; - result?; let set = GuardianSet { num_guardians: guardians.len(), expiration_time: 0 }; self.guardian_sets.write(set_index, set); @@ -195,7 +178,6 @@ mod wormhole { i += 1; }; self.current_guardian_set_index.write(set_index); - Result::Ok(()) } fn expire_guardian_set(ref self: ContractState, set_index: u32, now: u64) { @@ -208,41 +190,37 @@ mod wormhole { impl WormholeImpl of IWormhole { fn submit_new_guardian_set( ref self: ContractState, set_index: u32, guardians: Array - ) -> Result<(), SubmitNewGuardianSetError> { + ) { let execution_info = get_execution_info().unbox(); if self.owner.read() != execution_info.caller_address { - return Result::Err(SubmitNewGuardianSetError::AccessDenied); + panic_with_felt252(SubmitNewGuardianSetError::AccessDenied.into()); } let current_set_index = self.current_guardian_set_index.read(); if set_index != current_set_index + 1 { - return Result::Err(SubmitNewGuardianSetError::InvalidGuardianSetSequence.into()); + panic_with_felt252(SubmitNewGuardianSetError::InvalidGuardianSetSequence.into()); } - store_guardian_set(ref self, set_index, @guardians)?; + store_guardian_set(ref self, set_index, @guardians); expire_guardian_set( ref self, current_set_index, execution_info.block_info.unbox().block_timestamp ); - Result::Ok(()) } - fn parse_and_verify_vm( - self: @ContractState, encoded_vm: ByteArray - ) -> Result { - let (vm, body_hash) = parse_vm(encoded_vm)?; + fn parse_and_verify_vm(self: @ContractState, encoded_vm: ByteArray) -> VM { + let (vm, body_hash) = parse_vm(encoded_vm); let guardian_set = self.guardian_sets.read(vm.guardian_set_index); if guardian_set.num_guardians == 0 { - return Result::Err(ParseAndVerifyVmError::InvalidGuardianSetIndex); + panic_with_felt252(ParseAndVerifyVmError::InvalidGuardianSetIndex.into()); } if vm.guardian_set_index != self.current_guardian_set_index.read() && guardian_set.expiration_time < get_block_timestamp() { - return Result::Err(ParseAndVerifyVmError::GuardianSetExpired); + panic_with_felt252(ParseAndVerifyVmError::GuardianSetExpired.into()); } if vm.signatures.len() < quorum(guardian_set.num_guardians) { - return Result::Err(ParseAndVerifyVmError::NoQuorum); + panic_with_felt252(ParseAndVerifyVmError::NoQuorum.into()); } let mut signatures_clone = vm.signatures.clone(); let mut last_index = Option::None; - let mut result = Result::Ok(()); loop { let signature = match signatures_clone.pop_front() { Option::Some(v) => { v }, @@ -252,8 +230,7 @@ mod wormhole { match last_index { Option::Some(last_index) => { if *(@signature).guardian_index <= last_index { - result = Result::Err(ParseAndVerifyVmError::InvalidSignatureOrder); - break; + panic_with_felt252(ParseAndVerifyVmError::InvalidSignatureOrder.into()); } }, Option::None => {}, @@ -261,43 +238,33 @@ mod wormhole { last_index = Option::Some(*(@signature).guardian_index); if signature.guardian_index.into() >= guardian_set.num_guardians { - result = Result::Err(ParseAndVerifyVmError::InvalidGuardianIndex); - break; + panic_with_felt252(ParseAndVerifyVmError::InvalidGuardianIndex.into()); } let guardian_key = self .guardian_keys .read((vm.guardian_set_index, signature.guardian_index)); - let r = verify_signature(body_hash, signature.signature, guardian_key); - if r.is_err() { - result = r; - break; - } + verify_signature(body_hash, signature.signature, guardian_key); }; - result?; - - Result::Ok(vm) + vm } } - fn parse_signature(ref reader: Reader) -> Result { + fn parse_signature(ref reader: Reader) -> GuardianSignature { let guardian_index = reader.read_u8(); let r = reader.read_u256(); let s = reader.read_u256(); let recovery_id = reader.read_u8(); let y_parity = (recovery_id % 2) > 0; - let signature = GuardianSignature { - guardian_index, signature: Signature { r, s, y_parity } - }; - Result::Ok(signature) + GuardianSignature { guardian_index, signature: Signature { r, s, y_parity } } } - fn parse_vm(encoded_vm: ByteArray) -> Result<(VM, u256), ParseAndVerifyVmError> { + fn parse_vm(encoded_vm: ByteArray) -> (VM, u256) { let mut reader = ReaderImpl::new(encoded_vm); let version = reader.read_u8(); if version != 1 { - return Result::Err(ParseAndVerifyVmError::VmVersionIncompatible); + panic_with_felt252(ParseAndVerifyVmError::VmVersionIncompatible.into()); } let guardian_set_index = reader.read_u32(); @@ -305,22 +272,14 @@ mod wormhole { let mut i = 0; let mut signatures = array![]; - let mut result = Result::Ok(()); while i < sig_count { - match parse_signature(ref reader) { - Result::Ok(signature) => { signatures.append(signature); }, - Result::Err(err) => { - result = Result::Err(err); - break; - }, - } + signatures.append(parse_signature(ref reader)); i += 1; }; - result?; let mut reader_for_hash = reader.clone(); let mut hasher = HasherImpl::new(); - hasher.push_reader(ref reader_for_hash).map_err()?; + hasher.push_reader(ref reader_for_hash); let body_hash1 = hasher.finalize(); let mut hasher2 = HasherImpl::new(); hasher2.push_u256(body_hash1); @@ -347,32 +306,25 @@ mod wormhole { consistency_level, payload, }; - Result::Ok((vm, body_hash2)) + (vm, body_hash2) } - fn verify_signature( - body_hash: u256, signature: Signature, guardian_key: u256, - ) -> Result<(), ParseAndVerifyVmError> { + fn verify_signature(body_hash: u256, signature: Signature, guardian_key: u256,) { let point: Secp256k1Point = recover_public_key(body_hash, signature) - .ok_or(ParseAndVerifyVmError::InvalidSignature)?; - let address = eth_address(point)?; + .expect(ParseAndVerifyVmError::InvalidSignature.into()); + let address = eth_address(point); assert(guardian_key != 0, SubmitNewGuardianSetError::InvalidGuardianKey.into()); if address != guardian_key { - return Result::Err(ParseAndVerifyVmError::InvalidSignature); + panic_with_felt252(ParseAndVerifyVmError::InvalidSignature.into()); } - Result::Ok(()) } - fn eth_address(point: Secp256k1Point) -> Result { - let (x, y) = match point.get_coordinates() { - Result::Ok(v) => { v }, - Result::Err(_) => { return Result::Err(ParseAndVerifyVmError::InvalidSignature); }, - }; + fn eth_address(point: Secp256k1Point) -> u256 { + let (x, y) = point.get_coordinates().expect(ParseAndVerifyVmError::InvalidSignature.into()); let mut hasher = HasherImpl::new(); hasher.push_u256(x); hasher.push_u256(y); - let address = hasher.finalize() % ONE_SHIFT_160; - Result::Ok(address) + hasher.finalize() % ONE_SHIFT_160 } } diff --git a/target_chains/starknet/contracts/tests/wormhole.cairo b/target_chains/starknet/contracts/tests/wormhole.cairo index 591d75f4..a93d6b9b 100644 --- a/target_chains/starknet/contracts/tests/wormhole.cairo +++ b/target_chains/starknet/contracts/tests/wormhole.cairo @@ -11,7 +11,7 @@ fn test_parse_and_verify_vm_works() { let owner = 'owner'.try_into().unwrap(); let dispatcher = deploy_and_init(owner); - let vm = dispatcher.parse_and_verify_vm(good_vm1()).unwrap(); + let vm = dispatcher.parse_and_verify_vm(good_vm1()); assert!(vm.version == 1); assert!(vm.guardian_set_index == 3); assert!(vm.signatures.len() == 13); @@ -36,26 +36,13 @@ fn test_parse_and_verify_vm_works() { #[test] #[fuzzer(runs: 100, seed: 0)] -#[should_panic(expected: ('any_expected',))] +#[should_panic] fn test_parse_and_verify_vm_rejects_corrupted_vm(pos: usize, random1: usize, random2: usize) { let owner = 'owner'.try_into().unwrap(); let dispatcher = deploy_and_init(owner); - let r = dispatcher.parse_and_verify_vm(corrupted_vm(pos, random1, random2)); - match r { - Result::Ok(v) => { println!("no error, output: {:?}", v); }, - Result::Err(err) => { - if err == ParseAndVerifyVmError::InvalidSignature - || err == ParseAndVerifyVmError::InvalidGuardianIndex - || err == ParseAndVerifyVmError::InvalidGuardianSetIndex - || err == ParseAndVerifyVmError::VmVersionIncompatible - || err == ParseAndVerifyVmError::Reader(pyth::reader::Error::UnexpectedEndOfInput) { - panic_with_felt252('any_expected'); - } else { - panic_with_felt252(err.into()); - } - }, - } + let vm = dispatcher.parse_and_verify_vm(corrupted_vm(pos, random1, random2)); + println!("no error, output: {:?}", vm); } #[test] @@ -64,7 +51,7 @@ fn test_submit_guardian_set_rejects_wrong_owner() { let owner = 'owner'.try_into().unwrap(); let dispatcher = deploy(owner, guardian_set1()); start_prank(CheatTarget::One(dispatcher.contract_address), 'baddy'.try_into().unwrap()); - dispatcher.submit_new_guardian_set(1, guardian_set1()).unwrap_with_felt252(); + dispatcher.submit_new_guardian_set(1, guardian_set1()); } #[test] @@ -74,8 +61,8 @@ fn test_submit_guardian_set_rejects_wrong_index() { let dispatcher = deploy(owner, guardian_set1()); start_prank(CheatTarget::One(dispatcher.contract_address), owner.try_into().unwrap()); - dispatcher.submit_new_guardian_set(1, guardian_set1()).unwrap_with_felt252(); - dispatcher.submit_new_guardian_set(3, guardian_set3()).unwrap_with_felt252(); + dispatcher.submit_new_guardian_set(1, guardian_set1()); + dispatcher.submit_new_guardian_set(3, guardian_set3()); } #[test] @@ -92,7 +79,7 @@ fn test_submit_guardian_set_rejects_empty() { let dispatcher = deploy(owner, guardian_set1()); start_prank(CheatTarget::One(dispatcher.contract_address), owner.try_into().unwrap()); - dispatcher.submit_new_guardian_set(1, array![]).unwrap_with_felt252(); + dispatcher.submit_new_guardian_set(1, array![]); } fn deploy(owner: ContractAddress, guardians: Array) -> IWormholeDispatcher { @@ -113,9 +100,9 @@ pub fn deploy_and_init(owner: ContractAddress) -> IWormholeDispatcher { let dispatcher = deploy(owner, guardian_set1()); start_prank(CheatTarget::One(dispatcher.contract_address), owner.try_into().unwrap()); - dispatcher.submit_new_guardian_set(1, guardian_set1()).unwrap_with_felt252(); - dispatcher.submit_new_guardian_set(2, guardian_set2()).unwrap_with_felt252(); - dispatcher.submit_new_guardian_set(3, guardian_set3()).unwrap_with_felt252(); + dispatcher.submit_new_guardian_set(1, guardian_set1()); + dispatcher.submit_new_guardian_set(2, guardian_set2()); + dispatcher.submit_new_guardian_set(3, guardian_set3()); stop_prank(CheatTarget::One(dispatcher.contract_address)); dispatcher