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(core): Add nonce to program id generation #3010

Merged
merged 62 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
626eacf
Add nonce parameter to ProgramId::generate
mqxf Aug 2, 2023
c1ce6af
Merge branch 'master' of https://github.com/gear-tech/gear into ms/is…
mqxf Aug 2, 2023
726d292
Change InitPacket to not premake ProgramId. Fix tests in MessageContext
mqxf Aug 3, 2023
38d411d
Fix issues and remove unsafe
mqxf Aug 4, 2023
895cfe0
Add program id generation without nonce
mqxf Aug 7, 2023
409338e
Fix CI
mqxf Aug 7, 2023
e019488
Fix CI 2
mqxf Aug 8, 2023
23e9b9f
Fix CI 3
mqxf Aug 8, 2023
0d26504
Fix CI 4
mqxf Aug 9, 2023
161c61b
Fix CI 5
mqxf Aug 10, 2023
2a9ef1f
Changed InitMessage generation to include nonce
mqxf Aug 15, 2023
6c01552
Fix CI
mqxf Aug 15, 2023
c4a897a
Changed generation in MessageContext
mqxf Aug 19, 2023
9863e52
Removed trait and require MessageId for generation in context and pallet
mqxf Aug 20, 2023
6cac1ea
Fix CI
mqxf Aug 20, 2023
77cdcb1
Make clippy happy
mqxf Aug 21, 2023
fcc208e
Change error code
mqxf Aug 21, 2023
9de8247
Make docs comp happy
mqxf Aug 21, 2023
e69aec8
Fix CI
mqxf Aug 21, 2023
7cc5753
Requested changes
mqxf Aug 22, 2023
059303d
Remove unneeded check
mqxf Aug 22, 2023
1325c22
Move check to do_create_program
mqxf Aug 22, 2023
ed4d9f3
Changed uniquness verification
mqxf Aug 22, 2023
2cf074d
Changed ProgramId uniqueness check in upload_program_raw
mqxf Aug 22, 2023
8a3e804
Renamed functions
mqxf Aug 22, 2023
5a248b1
Changed generation to remove nonce
mqxf Aug 23, 2023
1f87a01
Merge branch 'master' into ms/issue-2821
mqxf Aug 23, 2023
56e75d6
Change messageId used and fix CI
mqxf Aug 24, 2023
94a9219
Fix CI
mqxf Aug 24, 2023
03aca89
Fix CI
mqxf Aug 24, 2023
4b7df1c
ProgramId pregenerated when making InitPacket
mqxf Aug 31, 2023
09244a7
Fic CI
mqxf Aug 31, 2023
c62f475
Changed option to propagating error
mqxf Aug 31, 2023
01383bb
Update core/src/ids.rs
mqxf Sep 4, 2023
5fdef09
Update core/src/message/context.rs
mqxf Sep 4, 2023
40b33c4
Fix issues
mqxf Sep 4, 2023
b6345d4
Potential fix CI: change parameter order
mqxf Sep 4, 2023
4e53a6e
Change signature to not affect gas_limit and value relative position
mqxf Sep 4, 2023
1a453be
Fix CI
mqxf Sep 4, 2023
662c7c6
Fix formatting
mqxf Sep 4, 2023
7aa9d49
Re-enabled Error::ProgramAlreadyExists returning from pallet
mqxf Sep 5, 2023
143a73e
Fix tests
mqxf Sep 6, 2023
45e1c77
Fix tests
mqxf Sep 6, 2023
d9929d6
Merge with master
mqxf Sep 6, 2023
faaeacd
Merge with master
mqxf Sep 6, 2023
b623272
Cargo fmt
mqxf Sep 6, 2023
dd73252
Fixed tests
mqxf Sep 6, 2023
84fbe9d
Refactor code and removed unnecessary moves
mqxf Sep 7, 2023
24cc688
Moved duplicate id check in pallets-gear
mqxf Sep 7, 2023
cc397d5
Made comment more clear
mqxf Sep 7, 2023
00aa530
Change comments
mqxf Sep 7, 2023
e968c7b
Change `calculate_program_id` to take `Option<MessageId>`
mqxf Sep 7, 2023
0e438b8
Replaced `match` with `if let`
mqxf Sep 7, 2023
0672b3e
Merge branch 'master' into ms/issue-2821
mqxf Sep 18, 2023
c7ccc63
Renamed functions and readded test
mqxf Sep 18, 2023
059390d
Fix clippy
mqxf Sep 18, 2023
febbe08
Merge remote-tracking branch 'origin/ms/issue-2821' into ms/issue-2821
mqxf Sep 18, 2023
4ae2773
Fix functions that were renamed
mqxf Sep 18, 2023
2f84a66
removed `.into()`
mqxf Sep 18, 2023
291fa7f
Added todo comment
mqxf Sep 21, 2023
9c788e5
Merge branch 'master' into ms/issue-2821
mqxf Sep 21, 2023
3cb6afb
Merge with master
mqxf Sep 21, 2023
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
7 changes: 6 additions & 1 deletion core-backend/common/src/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,13 @@ where
let salt = Self::read_message_payload(ctx, read_salt)?;
let payload = Self::read_message_payload(ctx, read_payload)?;

let message_id = ctx.ext_mut().message_id()?;

ctx.ext_mut()
.create_program(InitPacket::new(code_id.into(), salt, payload, value), delay)
.create_program(
InitPacket::new(code_id.into(), salt, payload, Some(message_id), value),
delay,
)
.map_err(Into::into)
}

Expand Down
3 changes: 2 additions & 1 deletion core-processor/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,8 @@ impl Externalities for Ext {
packet: InitPacket,
delay: u32,
) -> Result<(MessageId, ProgramId), Self::FallibleError> {
self.check_forbidden_destination(packet.destination())?;
mqxf marked this conversation as resolved.
Show resolved Hide resolved
// We don't check for forbidden destination here, since dest is always unique and almost impossible to match SYSTEM_ID

self.safe_gasfull_sends(&packet)?;
self.charge_expiring_resources(&packet, true)?;
self.charge_sending_fee(delay)?;
Expand Down
30 changes: 19 additions & 11 deletions core/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,20 @@ impl ProgramId {
pub const SYSTEM: Self = Self(*b"geargeargeargeargeargeargeargear");

/// Generate ProgramId from given CodeId and salt
pub fn generate(code_id: CodeId, salt: &[u8]) -> Self {
const SALT: &[u8] = b"program";
pub fn generate_from_user(code_id: CodeId, salt: &[u8]) -> Self {
const SALT: &[u8] = b"program_from_user";

let argument = [SALT, code_id.as_ref(), salt].concat();
hash(&argument).into()
}

/// Generate ProgramId from given CodeId, MessageId and salt
pub fn generate_from_program(code_id: CodeId, salt: &[u8], message_id: MessageId) -> Self {
const SALT: &[u8] = b"program_from_wasm";

let argument = [SALT, message_id.as_ref(), code_id.as_ref(), salt].concat();
hash(&argument).into()
}
}

declare_id!(ReservationId: "Reservation identifier");
Expand All @@ -229,36 +237,36 @@ fn formatting_test() {
use alloc::format;

let code_id = CodeId::generate(&[0, 1, 2]);
let id = ProgramId::generate(code_id, &[2, 1, 0]);
let id = ProgramId::generate_from_user(code_id, &[2, 1, 0]);

// `Debug`/`Display`.
assert_eq!(
format!("{id:?}"),
"0x227e53192dc14699539c44608810a8202d6a2bee92078e6913b1bdf38925fa67"
"0x6a519a19ffdfd8f45c310b44aecf156b080c713bf841a8cb695b0ea5f765ed3e"
);
// `Debug`/`Display` with precision 0.
assert_eq!(format!("{id:.0?}"), "0x..");
// `Debug`/`Display` with precision 1.
assert_eq!(format!("{id:.1?}"), "0x22..67");
assert_eq!(format!("{id:.1?}"), "0x6a..3e");
// `Debug`/`Display` with precision 2.
assert_eq!(format!("{id:.2?}"), "0x227e..fa67");
assert_eq!(format!("{id:.2?}"), "0x6a51..ed3e");
// `Debug`/`Display` with precision 4.
assert_eq!(format!("{id:.4?}"), "0x227e5319..8925fa67");
assert_eq!(format!("{id:.4?}"), "0x6a519a19..f765ed3e");
// `Debug`/`Display` with precision 15.
assert_eq!(
format!("{id:.15?}"),
"0x227e53192dc14699539c44608810a8..6a2bee92078e6913b1bdf38925fa67"
"0x6a519a19ffdfd8f45c310b44aecf15..0c713bf841a8cb695b0ea5f765ed3e"
);
// `Debug`/`Display` with precision 30 (the same for any case >= 16).
assert_eq!(
format!("{id:.30?}"),
"0x227e53192dc14699539c44608810a8202d6a2bee92078e6913b1bdf38925fa67"
"0x6a519a19ffdfd8f45c310b44aecf156b080c713bf841a8cb695b0ea5f765ed3e"
);
// Alternate formatter.
assert_eq!(
format!("{id:#}"),
"ProgramId(0x227e53192dc14699539c44608810a8202d6a2bee92078e6913b1bdf38925fa67)"
"ProgramId(0x6a519a19ffdfd8f45c310b44aecf156b080c713bf841a8cb695b0ea5f765ed3e)"
);
// Alternate formatter with precision 2.
assert_eq!(format!("{id:#.2}"), "ProgramId(0x227e..fa67)");
assert_eq!(format!("{id:#.2}"), "ProgramId(0x6a51..ed3e)");
}
24 changes: 21 additions & 3 deletions core/src/message/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ impl InitMessage {
}
}

// TODO: #issue 3320
/// Init message packet.
///
/// This structure is preparation for future init message sending. Has no message id.
Expand All @@ -131,9 +132,20 @@ pub struct InitPacket {

impl InitPacket {
/// Create new InitPacket without gas.
pub fn new(code_id: CodeId, salt: Salt, payload: Payload, value: Value) -> Self {
pub fn new(
code_id: CodeId,
salt: Salt,
payload: Payload,
message_id: Option<MessageId>,
mqxf marked this conversation as resolved.
Show resolved Hide resolved
value: Value,
) -> Self {
let program_id = if let Some(id) = message_id {
ProgramId::generate_from_program(code_id, salt.inner(), id)
} else {
ProgramId::generate_from_user(code_id, salt.inner())
};
Self {
program_id: ProgramId::generate(code_id, salt.inner()),
program_id,
code_id,
salt,
payload,
Expand All @@ -147,11 +159,17 @@ impl InitPacket {
code_id: CodeId,
salt: Salt,
payload: Payload,
message_id: Option<MessageId>,
gas_limit: GasLimit,
value: Value,
) -> Self {
let program_id = if let Some(id) = message_id {
ProgramId::generate_from_program(code_id, salt.inner(), id)
} else {
ProgramId::generate_from_user(code_id, salt.inner())
};
Self {
program_id: ProgramId::generate(code_id, salt.inner()),
program_id,
code_id,
salt,
payload,
Expand Down
27 changes: 20 additions & 7 deletions examples/program-factory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,13 @@ mod tests {
sys.init_logger();
let factory = prepare_factory(&sys);

let child_id_expected = calculate_program_id(CHILD_CODE_HASH.into(), &0i32.to_le_bytes());

// Send `handle` msg to factory to create a new child
let res = factory.send_bytes(10001, CreateProgram::Default.encode());
let child_id_expected = calculate_program_id(
CHILD_CODE_HASH.into(),
&0i32.to_le_bytes(),
Some(res.sent_message_id()),
);
assert!(!res.main_failed());
assert!(sys.is_active_program(child_id_expected));
}
Expand All @@ -108,20 +111,26 @@ mod tests {
let factory = prepare_factory(&sys);

let salt = 0i32.to_be_bytes();
let child_id_expected = calculate_program_id(CHILD_CODE_HASH.into(), &salt);
let payload = CreateProgram::Custom(vec![(CHILD_CODE_HASH, salt.to_vec(), 100_000_000)]);

// Send `handle` msg to factory to create a new child
let res = factory.send_bytes(10001, payload.encode());

let child_id_expected =
calculate_program_id(CHILD_CODE_HASH.into(), &salt, Some(res.sent_message_id()));

assert!(!res.main_failed());
assert!(sys.is_active_program(child_id_expected));

// Send `handle` msg to create a duplicate
let res = factory.send_bytes(10001, payload.encode());

let child_id_expected =
calculate_program_id(CHILD_CODE_HASH.into(), &salt, Some(res.sent_message_id()));

assert!(!res.main_failed());
// Init message, which is not processed. Error reply for that init is generated.
// Dispatch message is processed, no error replies, because message is sent to
// the original program.
assert!(sys.is_active_program(child_id_expected));

assert_eq!(res.total_processed(), 3 + 1 + 1); // +1 for the original message, initiated by user +1 for auto generated replies
}

Expand All @@ -134,9 +143,13 @@ mod tests {
// Non existing code hash provided
let non_existing_code_hash = [10u8; 32];
let salt = b"some_salt";
let fictional_program_id = calculate_program_id(non_existing_code_hash.into(), salt);
let payload = CreateProgram::Custom(vec![(non_existing_code_hash, salt.to_vec(), 100_000)]);
let res = factory.send_bytes(10001, payload.encode());
let fictional_program_id = calculate_program_id(
non_existing_code_hash.into(),
salt,
Some(res.sent_message_id()),
);
assert!(!res.main_failed());
// No new program with fictional id
assert!(sys.is_active_program(fictional_program_id));
Expand Down
2 changes: 1 addition & 1 deletion gcli/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub fn login_as_alice() -> Result<()> {

/// Generate program id from code id and salt
pub fn program_id(bin: &[u8], salt: &[u8]) -> ProgramId {
mqxf marked this conversation as resolved.
Show resolved Hide resolved
ProgramId::generate(CodeId::generate(bin), salt)
ProgramId::generate_from_user(CodeId::generate(bin), salt)
}

/// AccountId32 of `addr`
Expand Down
7 changes: 4 additions & 3 deletions gsdk/tests/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ async fn test_calculate_handle_gas() -> Result<()> {
let node = dev_node();

let salt = vec![];
let pid = ProgramId::generate(CodeId::generate(demo_messager::WASM_BINARY), &salt);
let pid = ProgramId::generate_from_user(CodeId::generate(demo_messager::WASM_BINARY), &salt);

// 1. upload program.
let signer = Api::new(Some(&node_uri(&node)))
Expand Down Expand Up @@ -150,7 +150,8 @@ async fn test_calculate_reply_gas() -> Result<()> {
let alice: [u8; 32] = *alice_account_id().as_ref();

let salt = vec![];
let pid = ProgramId::generate(CodeId::generate(demo_waiter::WASM_BINARY), &salt);

let pid = ProgramId::generate_from_user(CodeId::generate(demo_waiter::WASM_BINARY), &salt);
let payload = demo_waiter::Command::SendUpTo(alice, 10);

// 1. upload program.
Expand Down Expand Up @@ -294,7 +295,7 @@ async fn test_original_code_storage() -> Result<()> {
let node = dev_node();

let salt = vec![];
let pid = ProgramId::generate(CodeId::generate(demo_messager::WASM_BINARY), &salt);
let pid = ProgramId::generate_from_user(CodeId::generate(demo_messager::WASM_BINARY), &salt);

let signer = Api::new(Some(&node_uri(&node)))
.await?
Expand Down
8 changes: 6 additions & 2 deletions gtest/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,12 @@ fn read_file<P: AsRef<Path>>(path: P, extension: &str) -> Vec<u8> {
fs::read(&path).unwrap_or_else(|_| panic!("Failed to read file {:?}", path))
}

pub fn calculate_program_id(code_id: CodeId, salt: &[u8]) -> ProgramId {
ProgramId::generate(code_id, salt)
pub fn calculate_program_id(code_id: CodeId, salt: &[u8], id: Option<MessageId>) -> ProgramId {
if let Some(id) = id {
ProgramId::generate_from_program(code_id, salt, id)
} else {
ProgramId::generate_from_user(code_id, salt)
}
}

#[cfg(test)]
Expand Down
37 changes: 19 additions & 18 deletions pallets/gear-debug/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ fn debug_mode_works() {
let code_1 = utils::parse_wat(wat_1);
let code_2 = utils::parse_wat(wat_2);

let program_id_1 = ProgramId::generate(CodeId::generate(&code_1), DEFAULT_SALT);
let program_id_2 = ProgramId::generate(CodeId::generate(&code_2), DEFAULT_SALT);
let program_id_1 = ProgramId::generate_from_user(CodeId::generate(&code_1), DEFAULT_SALT);
let program_id_2 = ProgramId::generate_from_user(CodeId::generate(&code_2), DEFAULT_SALT);

PalletGear::<Test>::upload_program(
RuntimeOrigin::signed(1),
Expand Down Expand Up @@ -200,19 +200,19 @@ fn debug_mode_works() {
dispatch_queue: vec![],
programs: vec![
crate::ProgramDetails {
id: program_id_1,
id: program_id_2,
state: crate::ProgramState::Active(crate::ProgramInfo {
static_pages,
persistent_pages: Default::default(),
code_hash: utils::h256_code_hash(&code_1),
code_hash: utils::h256_code_hash(&code_2),
}),
},
crate::ProgramDetails {
id: program_id_2,
id: program_id_1,
state: crate::ProgramState::Active(crate::ProgramInfo {
static_pages,
persistent_pages: Default::default(),
code_hash: utils::h256_code_hash(&code_2),
code_hash: utils::h256_code_hash(&code_1),
}),
},
],
Expand Down Expand Up @@ -278,19 +278,19 @@ fn debug_mode_works() {
],
programs: vec![
crate::ProgramDetails {
id: program_id_1,
id: program_id_2,
state: crate::ProgramState::Active(crate::ProgramInfo {
static_pages,
persistent_pages: Default::default(),
code_hash: utils::h256_code_hash(&code_1),
code_hash: utils::h256_code_hash(&code_2),
}),
},
crate::ProgramDetails {
id: program_id_2,
id: program_id_1,
state: crate::ProgramState::Active(crate::ProgramInfo {
static_pages,
persistent_pages: Default::default(),
code_hash: utils::h256_code_hash(&code_2),
code_hash: utils::h256_code_hash(&code_1),
}),
},
],
Expand All @@ -307,19 +307,19 @@ fn debug_mode_works() {
dispatch_queue: vec![],
programs: vec![
crate::ProgramDetails {
id: program_id_1,
id: program_id_2,
state: crate::ProgramState::Active(crate::ProgramInfo {
static_pages,
persistent_pages: Default::default(),
code_hash: utils::h256_code_hash(&code_1),
code_hash: utils::h256_code_hash(&code_2),
}),
},
crate::ProgramDetails {
id: program_id_2,
id: program_id_1,
state: crate::ProgramState::Active(crate::ProgramInfo {
static_pages,
persistent_pages: Default::default(),
code_hash: utils::h256_code_hash(&code_2),
code_hash: utils::h256_code_hash(&code_1),
}),
},
],
Expand Down Expand Up @@ -513,7 +513,7 @@ fn check_not_allocated_pages() {
init_logger();
new_test_ext().execute_with(|| {
let code = parse_wat(wat);
let program_id = ProgramId::generate(CodeId::generate(&code), DEFAULT_SALT);
let program_id = ProgramId::generate_from_user(CodeId::generate(&code), DEFAULT_SALT);
let origin = RuntimeOrigin::signed(1);

assert_ok!(PalletGear::<Test>::upload_program(
Expand Down Expand Up @@ -732,7 +732,7 @@ fn check_changed_pages_in_storage() {
init_logger();
new_test_ext().execute_with(|| {
let code = parse_wat(wat);
let program_id = ProgramId::generate(CodeId::generate(&code), DEFAULT_SALT);
let program_id = ProgramId::generate_from_user(CodeId::generate(&code), DEFAULT_SALT);
let origin = RuntimeOrigin::signed(1);

// Code info. Must be in consensus with wasm code.
Expand Down Expand Up @@ -870,7 +870,7 @@ fn check_gear_stack_end() {
init_logger();
new_test_ext().execute_with(|| {
let code = utils::parse_wat(wat.as_str());
let program_id = ProgramId::generate(CodeId::generate(&code), DEFAULT_SALT);
let program_id = ProgramId::generate_from_user(CodeId::generate(&code), DEFAULT_SALT);
let origin = RuntimeOrigin::signed(1);

assert_ok!(PalletGear::<Test>::upload_program(
Expand Down Expand Up @@ -926,7 +926,8 @@ fn disabled_program_rent() {
init_logger();
new_test_ext().execute_with(|| {
let salt = b"salt".to_vec();
let pay_rent_id = ProgramId::generate(CodeId::generate(TEST_SYSCALLS_BINARY), &salt);
let pay_rent_id =
ProgramId::generate_from_user(CodeId::generate(TEST_SYSCALLS_BINARY), &salt);

let program_value = 10_000_000;
assert_ok!(Gear::upload_program(
Expand Down
Loading