Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Fix 16bit func_id (#11985)
Browse files Browse the repository at this point in the history
  • Loading branch information
kvinwang authored Aug 8, 2022
1 parent 8574647 commit 4ad36db
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 16 deletions.
4 changes: 2 additions & 2 deletions frame/contracts/src/chain_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
//!
//! However, only extensions implementing [`RegisteredChainExtension`] can be put into a tuple.
//! This is because the [`RegisteredChainExtension::ID`] is used to decide which of those extensions
//! should should be used when the contract calls a chain extensions. Extensions which are generally
//! should be used when the contract calls a chain extensions. Extensions which are generally
//! useful should claim their `ID` with [the registry](https://github.com/paritytech/chainextension-registry)
//! so that no collisions with other vendors will occur.
//!
Expand Down Expand Up @@ -215,7 +215,7 @@ where
/// It returns the two least significant bytes of the `id` passed by a contract as the other
/// two bytes represent the chain extension itself (the code which is calling this function).
pub fn func_id(&self) -> u16 {
(self.inner.id & 0x00FF) as u16
(self.inner.id & 0x0000FFFF) as u16
}

/// The chain extension id within the `id` passed by a contract.
Expand Down
29 changes: 15 additions & 14 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,28 +158,28 @@ impl ChainExtension<Test> for TestExtension {
let func_id = env.func_id();
let id = env.ext_id() as u32 | func_id as u32;
match func_id {
0 => {
0x8000 => {
let mut env = env.buf_in_buf_out();
let input = env.read(8)?;
env.write(&input, false, None)?;
TEST_EXTENSION.with(|e| e.borrow_mut().last_seen_buffer = input);
Ok(RetVal::Converging(id))
},
1 => {
0x8001 => {
let env = env.only_in();
TEST_EXTENSION.with(|e| {
e.borrow_mut().last_seen_inputs =
(env.val0(), env.val1(), env.val2(), env.val3())
});
Ok(RetVal::Converging(id))
},
2 => {
0x8002 => {
let mut env = env.buf_in_buf_out();
let weight = env.read(5)?[4].into();
env.charge_weight(weight)?;
Ok(RetVal::Converging(id))
},
3 => Ok(RetVal::Diverging { flags: ReturnFlags::REVERT, data: vec![42, 99] }),
0x8003 => Ok(RetVal::Diverging { flags: ReturnFlags::REVERT, data: vec![42, 99] }),
_ => {
panic!("Passed unknown id to test chain extension: {}", func_id);
},
Expand Down Expand Up @@ -1646,36 +1646,37 @@ fn chain_extension_works() {
),);
let addr = Contracts::contract_address(&ALICE, &hash, &[]);

// 0 = read input buffer and pass it through as output
let input: Vec<u8> = ExtensionInput { extension_id: 0, func_id: 0, extra: &[99] }.into();
// 0x8000 = read input buffer and pass it through as output
let input: Vec<u8> =
ExtensionInput { extension_id: 0, func_id: 0x8000, extra: &[99] }.into();
let result =
Contracts::bare_call(ALICE, addr.clone(), 0, GAS_LIMIT, None, input.clone(), false);
assert_eq!(TestExtension::last_seen_buffer(), input);
assert_eq!(result.result.unwrap().data, Bytes(input));

// 1 = treat inputs as integer primitives and store the supplied integers
// 0x8001 = treat inputs as integer primitives and store the supplied integers
Contracts::bare_call(
ALICE,
addr.clone(),
0,
GAS_LIMIT,
None,
ExtensionInput { extension_id: 0, func_id: 1, extra: &[] }.into(),
ExtensionInput { extension_id: 0, func_id: 0x8001, extra: &[] }.into(),
false,
)
.result
.unwrap();
// those values passed in the fixture
assert_eq!(TestExtension::last_seen_inputs(), (4, 4, 16, 12));

// 2 = charge some extra weight (amount supplied in the fifth byte)
// 0x8002 = charge some extra weight (amount supplied in the fifth byte)
let result = Contracts::bare_call(
ALICE,
addr.clone(),
0,
GAS_LIMIT,
None,
ExtensionInput { extension_id: 0, func_id: 2, extra: &[0] }.into(),
ExtensionInput { extension_id: 0, func_id: 0x8002, extra: &[0] }.into(),
false,
);
assert_ok!(result.result);
Expand All @@ -1686,7 +1687,7 @@ fn chain_extension_works() {
0,
GAS_LIMIT,
None,
ExtensionInput { extension_id: 0, func_id: 2, extra: &[42] }.into(),
ExtensionInput { extension_id: 0, func_id: 0x8002, extra: &[42] }.into(),
false,
);
assert_ok!(result.result);
Expand All @@ -1697,20 +1698,20 @@ fn chain_extension_works() {
0,
GAS_LIMIT,
None,
ExtensionInput { extension_id: 0, func_id: 2, extra: &[95] }.into(),
ExtensionInput { extension_id: 0, func_id: 0x8002, extra: &[95] }.into(),
false,
);
assert_ok!(result.result);
assert_eq!(result.gas_consumed, gas_consumed + 95);

// 3 = diverging chain extension call that sets flags to 0x1 and returns a fixed buffer
// 0x8003 = diverging chain extension call that sets flags to 0x1 and returns a fixed buffer
let result = Contracts::bare_call(
ALICE,
addr.clone(),
0,
GAS_LIMIT,
None,
ExtensionInput { extension_id: 0, func_id: 3, extra: &[] }.into(),
ExtensionInput { extension_id: 0, func_id: 0x8003, extra: &[] }.into(),
false,
)
.result
Expand Down

0 comments on commit 4ad36db

Please sign in to comment.