Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
fix: hyperdrive process_message
Browse files Browse the repository at this point in the history
execute it in revertable storage layer
  • Loading branch information
gitsimon committed Jun 30, 2023
1 parent fd1aea9 commit 676100a
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 2 deletions.
12 changes: 11 additions & 1 deletion pallets/hyperdrive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub mod pallet {

use frame_support::dispatch::PostDispatchInfo;
use frame_support::traits::Get;
use frame_support::transactional;
use frame_support::{
pallet_prelude::*,
sp_runtime::traits::{
Expand Down Expand Up @@ -409,9 +410,13 @@ pub mod pallet {
<CurrentTargetChainOwner<T, I>>::set(owner);
}

/// Processes a message with `key and `payload`.
///
/// **When action processing fails, the message sequence increment above is still persisted, only side-effects produced by the action should be reverted**.
/// See [`Self::process_action()`].
fn process_message(
key_bytes: &Vec<u8>,
message_bytes: &Vec<u8>,
payload_bytes: &Vec<u8>,
) -> Result<(), ProcessMessageResult> {
let message_id = T::MessageParser::parse_key(key_bytes)
.map_err(|_| ProcessMessageResult::ParsingKeyFailed)?;
Expand All @@ -422,6 +427,11 @@ pub mod pallet {
);
<MessageSequenceId<T, I>>::set(message_id);

Self::process_action(payload_bytes)
}

#[transactional]
fn process_action(message_bytes: &Vec<u8>) -> Result<(), ProcessMessageResult> {
let action = T::MessageParser::parse_value(message_bytes)
.map_err(|_| ProcessMessageResult::ParsingValueFailed)?;
let raw_action: RawAction = (&action).into();
Expand Down
98 changes: 97 additions & 1 deletion pallets/hyperdrive/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,12 @@ fn test_verify_proof() {
}

#[test]
fn test_send_message() {
fn test_send_message_value_parsing_fails() {
let mut test = new_test_ext();

test.execute_with(|| {
let seq_id_before = TezosHyperdrive::message_seq_id();

let actions = vec![
StateTransmitterUpdate::Add(
alice_account_id(),
Expand Down Expand Up @@ -429,5 +431,99 @@ fn test_send_message() {
value
)
);

// seq_id was incremented despite payload parsing failed
assert_eq!(TezosHyperdrive::message_seq_id(), seq_id_before + 1);

assert_eq!(
events()[5],
RuntimeEvent::TezosHyperdrive(crate::Event::MessageProcessed(ProcessMessageResult::ParsingValueFailed)),
);
});
}

#[test]
fn test_send_message() {
let mut test = new_test_ext();

test.execute_with(|| {
// pretend given message seq_id was just before test message 75 arrives
let seq_id_before = 74;
<crate::MessageSequenceId::<Test>>::set(seq_id_before);


let actions = vec![
StateTransmitterUpdate::Add(
alice_account_id(),
ActivityWindow {
start_block: 10,
end_block: 20,
},
),
StateTransmitterUpdate::Add(
bob_account_id(),
ActivityWindow {
start_block: 10,
end_block: 50,
},
),
];

let tezos_contract = StateOwner::try_from(hex!("050a000000160199651cbe1a155a5c8e5af7d6ea5c3f48eebb8c9c00").to_vec()).unwrap();
assert_ok!(TezosHyperdrive::update_target_chain_owner(
RuntimeOrigin::root().into(),
tezos_contract.clone()
));

assert_eq!(TezosHyperdrive::current_target_chain_owner(), tezos_contract);

assert_ok!(TezosHyperdrive::update_state_transmitters(
RuntimeOrigin::root().into(),
StateTransmitterUpdates::<Test>::try_from(actions).unwrap()
));

System::set_block_number(10);

let snapshot_root_1 = H256(hex!(
"8303857bb23c1b072d9b52409fffe7cf6de57c33b2776c7de170ec94d01f02fc"
));
assert_ok!(
TezosHyperdrive::submit_state_merkle_root(
RuntimeOrigin::signed(alice_account_id()),
1,
snapshot_root_1
)
);
assert_ok!(
TezosHyperdrive::submit_state_merkle_root(
RuntimeOrigin::signed(bob_account_id()),
1,
snapshot_root_1
)
);

assert_eq!(TezosHyperdrive::validate_state_merkle_root(1, snapshot_root_1), true);

let proof: StateProof<H256> = bounded_vec![];
let key = StateKey::try_from(hex!("05008b01").to_vec()).unwrap();
let value = StateValue::try_from(hex!("050707010000000c52454749535445525f4a4f4207070a00000016000016e64994c2ddbd293695b63e4cade029d3c8b5e30a000000ec050707030a0707050902000000250a00000020d80a8b0d800a3320528693947f7317871b2d51e5f3c8f3d0d4e4f7e6938ed68f070707070509020000002907070a00000020d80a8b0d800a3320528693947f7317871b2d51e5f3c8f3d0d4e4f7e6938ed68f00000707050900000707008080e898a9bf8d0700010707001d0707000107070001070702000000000707070700b40707070080cfb1eca062070700a0a9070707000000a0a5aaeca06207070a00000035697066733a2f2f516d536e317252737a444b354258634e516d4e367543767a4d376858636548555569426b61777758396b534d474b0000").to_vec()).unwrap();

assert_ok!(
TezosHyperdrive::submit_message(
RuntimeOrigin::signed(alice_account_id()),
1,
proof,
key,
value
)
);

// seq_id was incremented despite payload parsing failed
assert_eq!(TezosHyperdrive::message_seq_id(), seq_id_before + 1);

assert_eq!(
events()[5],
RuntimeEvent::TezosHyperdrive(crate::Event::MessageProcessed(ProcessMessageResult::ActionSuccess)),
);
});
}
7 changes: 7 additions & 0 deletions pallets/hyperdrive/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,11 @@ pub enum ProcessMessageResult {
ActionFailed(RawAction),
ActionSuccess,
InvalidSequenceId,
ProcessingFailed(DispatchError),
}

impl From<DispatchError> for ProcessMessageResult {
fn from(value: DispatchError) -> Self {
ProcessMessageResult::ProcessingFailed(value)
}
}

0 comments on commit 676100a

Please sign in to comment.