Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ethexe): simplify program creation and message sending in tests #4455

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all 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
199 changes: 106 additions & 93 deletions ethexe/service/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,22 +155,28 @@ async fn ping() {
.expect("After approval, instrumented code is guaranteed to be in the database");

let res = env
.create_program(code_id, b"PING", 0)
.create_program(code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();
assert_eq!(res.code_id, code_id);
assert_eq!(res.init_message_source, env.sender_id);
assert_eq!(res.init_message_payload, b"PING");
assert_eq!(res.init_message_value, 0);
assert_eq!(res.reply_payload, b"PONG");
assert_eq!(res.reply_value, 0);

let res = env
.send_message(res.program_id, b"PING", 0)
.await
.unwrap()
.wait_for()
.await
.unwrap();

assert_eq!(
res.reply_code,
ReplyCode::Success(SuccessReplyReason::Manual)
);
assert_eq!(res.reply_payload, b"PONG");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall refactor would be good as well

Suggested change
assert_eq!(res.reply_payload, b"PONG");
assert_eq!(reply.payload, b"PONG"); // etc

assert_eq!(res.reply_value, 0);

let ping_id = res.program_id;

Expand Down Expand Up @@ -234,15 +240,23 @@ async fn uninitialized_program() {
// Case #1: Init failed due to panic in init (decoding).
{
let res = env
.create_program(code_id, &[], 0)
.create_program(code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();

let reply = env
.send_message(res.program_id, &[], 0)
.await
.unwrap()
.wait_for()
.await
.unwrap();

let expected_err = ReplyCode::Error(SimpleExecutionError::UserspacePanic.into());
assert_eq!(res.reply_code, expected_err);
assert_eq!(reply.reply_code, expected_err);

let res = env
.send_message(res.program_id, &[], 0)
Expand All @@ -267,8 +281,17 @@ async fn uninitialized_program() {

let mut listener = env.events_publisher().subscribe().await;

let init_res = env.create_program(code_id, &init_payload, 0).await.unwrap();

let init_res = env
.create_program(code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();
let init_reply = env
.send_message(init_res.program_id, &init_payload, 0)
.await
.unwrap();
let mirror = env.ethereum.mirror(init_res.program_id.try_into().unwrap());

let mut msgs_for_reply = vec![];
Expand Down Expand Up @@ -323,7 +346,7 @@ async fn uninitialized_program() {
reply_to,
..
},
} if actor_id == init_res.program_id && reply_to == init_res.message_id => {
} if actor_id == init_res.program_id && reply_to == init_reply.message_id => {
Ok(Some(reply_code))
}
_ => Ok(None),
Expand Down Expand Up @@ -375,14 +398,24 @@ async fn mailbox() {
let code_id = res.code_id;

let res = env
.create_program(code_id, &env.sender_id.encode(), 0)
.create_program(code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();

assert_eq!(res.reply_code, ReplyCode::Success(SuccessReplyReason::Auto));
let init_res = env
.send_message(res.program_id, &env.sender_id.encode(), 0)
.await
.unwrap()
.wait_for()
.await
.unwrap();
assert_eq!(
init_res.reply_code,
ReplyCode::Success(SuccessReplyReason::Auto)
);

let pid = res.program_id;

Expand Down Expand Up @@ -553,9 +586,16 @@ async fn incoming_transfers() {
.unwrap();

let code_id = res.code_id;

let res = env
.create_program(code_id, b"PING", 0)
.create_program(code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();

let _ = env
.send_message(res.program_id, &env.sender_id.encode(), 0)
.await
.unwrap()
.wait_for()
Expand Down Expand Up @@ -663,8 +703,11 @@ async fn ping_reorg() {
log::info!("📗 Abort service to simulate node blocks skipping");
node.stop_service().await;

let create_program = env.create_program(code_id, b"PING", 0).await.unwrap();

let create_program = env.create_program(code_id).await.unwrap();
let init = env
.send_message(create_program.program_id, b"PING", 0)
.await
.unwrap();
// Mine some blocks to check missed blocks support
env.skip_blocks(10).await;

Expand All @@ -675,8 +718,9 @@ async fn ping_reorg() {
env.force_new_block().await;

let res = create_program.wait_for().await.unwrap();
let init_res = init.wait_for().await.unwrap();
assert_eq!(res.code_id, code_id);
assert_eq!(res.reply_payload, b"PONG");
assert_eq!(init_res.reply_payload, b"PONG");

let ping_id = res.program_id;

Expand Down Expand Up @@ -766,19 +810,24 @@ async fn ping_deep_sync() {
let code_id = res.code_id;

let res = env
.create_program(code_id, b"PING", 0)
.create_program(code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();
let init_res = env
.send_message(res.program_id, b"PING", 0)
.await
.unwrap()
.wait_for()
.await
.unwrap();
assert_eq!(res.code_id, code_id);
assert_eq!(res.init_message_payload, b"PING");
assert_eq!(res.init_message_value, 0);
assert_eq!(res.reply_payload, b"PONG");
assert_eq!(res.reply_value, 0);
assert_eq!(init_res.reply_payload, b"PONG");
assert_eq!(init_res.reply_value, 0);
assert_eq!(
res.reply_code,
init_res.reply_code,
ReplyCode::Success(SuccessReplyReason::Manual)
);

Expand Down Expand Up @@ -861,18 +910,26 @@ async fn multiple_validators() {
let ping_code_id = res.code_id;

let res = env
.create_program(ping_code_id, b"", 0)
.create_program(ping_code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();
let init_res = env
.send_message(res.program_id, b"", 0)
.await
.unwrap()
.wait_for()
.await
.unwrap();
assert_eq!(res.code_id, ping_code_id);
assert_eq!(res.init_message_payload, b"");
assert_eq!(res.init_message_value, 0);
assert_eq!(res.reply_payload, b"");
assert_eq!(res.reply_value, 0);
assert_eq!(res.reply_code, ReplyCode::Success(SuccessReplyReason::Auto));
assert_eq!(init_res.reply_payload, b"");
assert_eq!(init_res.reply_value, 0);
assert_eq!(
init_res.reply_code,
ReplyCode::Success(SuccessReplyReason::Auto)
);

let ping_id = res.program_id;

Expand All @@ -889,18 +946,26 @@ async fn multiple_validators() {
let async_code_id = res.code_id;

let res = env
.create_program(async_code_id, ping_id.encode().as_slice(), 0)
.create_program(async_code_id)
.await
.unwrap()
.wait_for()
.await
.unwrap();
let init_res = env
.send_message(res.program_id, ping_id.encode().as_slice(), 0)
.await
.unwrap()
.wait_for()
.await
.unwrap();
assert_eq!(res.code_id, async_code_id);
assert_eq!(res.init_message_payload, ping_id.encode().as_slice());
assert_eq!(res.init_message_value, 0);
assert_eq!(res.reply_payload, b"");
assert_eq!(res.reply_value, 0);
assert_eq!(res.reply_code, ReplyCode::Success(SuccessReplyReason::Auto));
assert_eq!(init_res.reply_payload, b"");
assert_eq!(init_res.reply_value, 0);
assert_eq!(
init_res.reply_code,
ReplyCode::Success(SuccessReplyReason::Auto)
);

let async_id = res.program_id;

Expand Down Expand Up @@ -1202,18 +1267,10 @@ mod utils {
}

// TODO (breathx): split it into different functions WITHIN THE PR.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm todo

pub async fn create_program(
&self,
code_id: CodeId,
payload: &[u8],
value: u128,
) -> Result<WaitForProgramCreation> {
pub async fn create_program(&self, code_id: CodeId) -> Result<WaitForProgramCreation> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rm EXECUTABLE BALANCE constant in favor of func argument / another func that will create program and topup balance

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so in case of absence of exec balance there's no need in approve

const EXECUTABLE_BALANCE: u128 = 500_000_000_000_000;

log::info!(
"📗 Create program, code_id {code_id}, payload len {}",
payload.len()
);
log::info!("📗 Create program, code_id {code_id}");

let listener = self.events_publisher().subscribe().await;

Expand All @@ -1225,19 +1282,16 @@ mod utils {

router
.wvara()
.approve(program_address, value + EXECUTABLE_BALANCE)
.approve(program_address, EXECUTABLE_BALANCE)
.await?;

let mirror = self.ethereum.mirror(program_address.into_array().into());

mirror.executable_balance_top_up(EXECUTABLE_BALANCE).await?;

let (_, message_id) = mirror.send_message(payload, value).await?;

Ok(WaitForProgramCreation {
listener,
program_id,
message_id,
})
}

Expand Down Expand Up @@ -1702,80 +1756,39 @@ mod utils {
pub struct WaitForProgramCreation {
listener: EventsListener,
pub program_id: ActorId,
pub message_id: MessageId,
}

#[derive(Debug)]
pub struct ProgramCreationInfo {
pub program_id: ActorId,
pub code_id: CodeId,
pub init_message_source: ActorId,
pub init_message_payload: Vec<u8>,
pub init_message_value: u128,
pub reply_payload: Vec<u8>,
pub reply_code: ReplyCode,
pub reply_value: u128,
}

impl WaitForProgramCreation {
pub async fn wait_for(mut self) -> Result<ProgramCreationInfo> {
log::info!("📗 Waiting for program {} creation", self.program_id);

let mut code_id_info = None;
let mut init_message_info = None;
let mut reply_info = None;

self.listener
.apply_until_block_event(|event| {
match event {
BlockEvent::Router(RouterEvent::ProgramCreated { actor_id, code_id })
if actor_id == self.program_id =>
{
code_id_info = Some(code_id);
return Ok(Some(()));
}
BlockEvent::Mirror { actor_id, event } if actor_id == self.program_id => {
match event {
MirrorEvent::MessageQueueingRequested {
source,
payload,
value,
..
} => {
init_message_info = Some((source, payload, value));
}
MirrorEvent::Reply {
payload,
reply_to,
reply_code,
value,
} if self.message_id == reply_to => {
reply_info = Some((payload, reply_code, value));
return Ok(Some(()));
}
_ => {}
}
}

_ => {}
}
Ok(None)
})
.await?;

let code_id = code_id_info.expect("Code ID must be set");
let (init_message_source, init_message_payload, init_message_value) =
init_message_info.expect("Init message info must be set");
let (reply_payload, reply_code, reply_value) =
reply_info.expect("Reply info must be set");

Ok(ProgramCreationInfo {
program_id: self.program_id,
code_id,
init_message_source,
init_message_payload,
init_message_value,
reply_payload,
reply_code,
reply_value,
})
}
}
Expand Down
Loading